我的智慧结束了。
我有一个HTTP处理程序(ImageHandler.ashx),它发送下来的图像(已调整大小),它是一个标准的HTTP处理程序(尝试使用Reusable true和false),它使用Image.GetThumbnailImage来调整大小并返回缩略图
我是一个asp Datalist控件,它有一个带有html图像控件的表。
<asp:DataList ID="listImg" runat="server" RepeatColumns="4" RepeatDirection="Horizontal"
ShowFooter="false" ShowHeader="false">
<ItemTemplate>
<table width="220px">
<tr width="100%">
<td>
<img src="Scripts/ImageHandler.ashx?width=125&image=Upload/<%# DataBinder.Eval(Container.DataItem, "photo") %>"
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
正如您所看到的,Handler需要的参数是宽度和图像路径。
此Datalist绑定到数据表(ImageData),该数据表提供要显示的图像列表。
到目前为止一切都有道理,现在问题就在这里 - 说我加载5张图片,即我的ImageData DataTable有5行,给定只显示3-4张图片,其余的只是想出一个红色的X,就像你没有图像一样。现在,如果您查看代码并导航到图像src,如 -
http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg
你会看到图像,他们都没有丢失图像。重新加载,他们又回来了。
我在Firefox中运行它并打开了Firebug,当我查看Images选项卡时,所有图像都是根据Firebug返回的(状态200 OK,我在Response选项卡中看到了Image),它就像Web服务器只是不显示其中的一些。请注意,并不总是处理/加载时间最长的图像丢失,而是一些随机的图像。
这可能会发生什么?
谢谢。
编辑1 - 添加处理程序代码(原始),我们继承了此代码。我已从此处的代码中删除了缓存,但生成的FYI缩略图已缓存。
public class ImageHandler : IHttpHandler{
public int _width;
public int _height;
public int _percent;
public string imageURL;
public void ProcessRequest(HttpContext context)
{
try
{
Bitmap bitOutput;
string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]);
String strArquivo = appPath + context.Request.QueryString["image"].Replace("/", "\\");
if (!(String.IsNullOrEmpty(context.Request["width"])))
{
Bitmap bitInput = GetImage(context);
if (SetHeightWidth(context, bitInput))
{ bitOutput = ResizeImage(bitInput, _width, _height, _percent); }
else { bitOutput = bitInput; }
context.Response.ContentType = "image/jpeg";
bitOutput.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
return;
}
catch (Exception ex) { /*HttpContext.Current.Response.Write(ex.Message);*/ }
}
/// <summary>
/// Get the image requested via the query string.
/// </summary>
public Bitmap GetImage(HttpContext context)
{
try
{
if (context.Cache[("ImagePath-" + context.Request.QueryString["image"])] == null)
{
string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]);
appPath = appPath + context.Request.QueryString["image"].Replace("/", "\\");
Bitmap bitOutput;
imageURL = appPath;
bitOutput = new Bitmap(appPath);
return bitOutput;
}
else
{
return (Bitmap)context.Cache[("ImagePath-" + context.Request.QueryString["image"])];
}
}
catch (Exception ex) { throw ex; }
}
/// <summary>
/// Set the height and width of the handler class.
/// </summary>
public bool SetHeightWidth(HttpContext context, Bitmap bitInput)
{
try
{
double inputRatio = Convert.ToDouble(bitInput.Width) / Convert.ToDouble(bitInput.Height);
if (!(String.IsNullOrEmpty(context.Request["width"])) && !(String.IsNullOrEmpty(context.Request["height"])))
{
_width = Int32.Parse(context.Request["width"]);
_height = Int32.Parse(context.Request["height"]);
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["width"])))
{
_width = Int32.Parse(context.Request["width"]);
_height = Convert.ToInt32((_width / inputRatio));
if (_width == 400 &&_height > 500)
{
_height = 500;
_width = Convert.ToInt32(500 * inputRatio);
}
else if (_width == 125 && _height > 200)
{
_height = 200;
_width = Convert.ToInt32(200 * inputRatio);
}
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["height"])))
{
_height = Int32.Parse(context.Request["height"]);
_width = Convert.ToInt32((_height * inputRatio));
return true;
}
else if (!(String.IsNullOrEmpty(context.Request["percent"])))
{
_height = bitInput.Height;
_width = bitInput.Width;
_percent = Int32.Parse(context.Request["percent"]);
return true;
}
else
{
_height = bitInput.Height;
_width = bitInput.Width;
return false;
}
}
catch (Exception ex) { throw ex; }
}
/// <summary>
/// Resizes bitmap using high quality algorithms.
/// </summary>
public static Bitmap ResizeImage(Bitmap originalBitmap, int newWidth, int newHeight, int newPercent)
{
try
{
if (newPercent != 0)
{
newWidth = Convert.ToInt32(originalBitmap.Width * (newPercent * .01));
newHeight = Convert.ToInt32(originalBitmap.Height * (newPercent * .01));
}
Bitmap inputBitmap = originalBitmap;
Bitmap resizedBitmap = new Bitmap(newWidth, newHeight, PixelFormat.Format64bppPArgb);
Graphics g = Graphics.FromImage(resizedBitmap);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
Rectangle rectangle = new Rectangle(0, 0, newWidth, newHeight);
g.DrawImage(inputBitmap, rectangle, 0, 0, inputBitmap.Width, inputBitmap.Height, GraphicsUnit.Pixel);
g.Dispose();
return resizedBitmap;
}
catch (Exception ex) { throw ex; }
}
public bool IsReusable
{
get
{
return true;
}
}}
编辑2 如果有人想要测试这一切,那么这里是从预定义文件夹中随机选取图像的代码,以创建aspDataList(listImg)是的DataTable(ImageData)绑定 -
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(Server.MapPath("Upload"));
System.IO.FileInfo[] files = dirInfo.GetFiles();
int fileCount = files.Length;
System.Data.DataTable ImageData = new System.Data.DataTable();
System.Data.DataColumn dCol = new System.Data.DataColumn("photo");
ImageData.Columns.Add(dCol);
System.Random rnd = new Random();
int nxtNumber = 0;
System.Data.DataRow dRow = null;
string fileName = string.Empty;
for (int i = 0; i < 20; i++)
{
dRow = ImageData.NewRow();
nxtNumber = rnd.Next(fileCount);
while (!files[nxtNumber].Extension.Equals(".jpg"))
{
nxtNumber = rnd.Next(fileCount);
}
fileName = files[nxtNumber].Name;
dRow["photo"] = fileName;
ImageData.Rows.Add(dRow);
}
listImg.DataSource = ImageData;
listImg.DataBind();
答案 0 :(得分:0)
尝试编码url的查询字符串,例如:
http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg
urlencode to
http://localhost:3540/Scripts/ImageHandler.ashx?width%3D150%26image%3DUpload%2FTest123.jpg
答案 1 :(得分:0)
我认为您的实际代码包含/&gt;在img标签的末尾??? 如果没有,你可以尝试先添加它并重新测试。
不是真正的答案,但你可以尝试将img标签更改为asp:Label并将文件名显示为文本而不是显示图像只是为了查看数据表是否正确构建。由于您可以直接访问图像处理程序时看到图像,我会说它与代码隐藏中的数据表构造有关。
当我做了类似的事情时,我通常将图像存储在SQL DB中,并使用图像处理程序返回查询字符串中带有记录ID的图像。这意味着您将返回现有的记录表,而不必根据文件夹的内容创建记录表。
答案 2 :(得分:0)
这里有趣的是 - 服务器上的相同代码以更可预测的方式运行,我可能仍然有几个丢失的图像,但现在它就像1个丢失,平均说30-40而不是1在我当地的环境中每5个人。 由于这些请求是异步的,它可能与它运行的机器的实际CPU有关,服务器更适合处理多个请求而不是我的可爱笔记本电脑?
无论是哪种方式我都修改了代码,所以此时没有涉及重新调整大小,处理程序代码只是获取重新调整大小的图像,而且一切都很好。
感谢大家的投入。