【问题标题】:Resizing Images using HTTP Handler ASP.Net, some images not showing up使用 HTTP 处理程序 ASP.Net 调整图像大小,一些图像未显示
【发布时间】:2013-04-15 21:00:17
【问题描述】:

到此为止,我已经束手无策了。

我有一个 HTTP 处理程序 (ImageHandler.ashx) 发送图像(调整大小),它是一个标准 HTTP 处理程序(使用可重用 true 和 false 进行尝试),它使用 Image.GetThumbnailImage 调整大小并返回缩略图。

我有一个带有 html 图像控件的表格的 asp Datalist 控件。

     <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,当我查看图像选项卡时,所有图像都根据 Firebug 返回(状态 200 正常,我在响应选项卡中看到图像),就像 Web 服务器一样不显示其中一些。请注意,处理/加载时间最长的图像并不总是丢失,而是一些随机图像。

这里会发生什么?

谢谢。

EDIT 1- 添加处理程序代码(原始),我们继承了此代码。我已经从这里的代码中删除了缓存,但仅供参考的缩略图一旦生成就会被缓存。

    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();

【问题讨论】:

  • 您可以发布处理程序代码吗?也许那里有些东西有时会返回一个空图像。另外,当你说图像在 Firebug 中有 200 个状态时,它们是否也有内容?它应该告诉你返回的字节数。
  • 是的,它显示内容(图像)和大小。此外,它并不总是显示为空的相同图像,如果我要多次显示相同的集合而没有缓存,它是一个消失的随机图像。一旦我从那里删除不必要的东西,我会稍后发布处理程序代码。
  • 这不是一个答案,而是一个建议。你可能想看看这个 nuget 包:nuget.org/packages/ImageResizer 它有几个用于 gif 调整大小等的额外包。
  • 谢谢,我去看看。
  • 开始简化代码,直到问题消失。尝试发送恒定颜色、未调整大小的图像等。

标签: asp.net ihttphandler


【解决方案1】:

尝试编码 url 的查询字符串,例如:

http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg

urlencode 到

http://localhost:3540/Scripts/ImageHandler.ashx?width%3D150%26image%3DUpload%2FTest123.jpg

【讨论】:

    【解决方案2】:

    我认为您的实际代码在 img 标签的末尾包含 /> ??? 如果没有,您可以尝试先添加它并重新测试。

    不是一个真正的答案,但您可以尝试将 img 标记更改为 asp:Label 并将文件名显示为文本,而不是仅显示图像以查看数据表是否正确构建。当您直接访问图像处理程序时可以看到图像,我会说它与代码隐藏中的数据表构造有关。

    当我做过类似的事情时,我通常将图像存储在 SQL DB 中,并使用图像处理程序在查询字符串中返回带有记录 ID 的图像。这意味着您将返回一个现有的记录表,而不必根据文件夹的内容创建一个。

    【讨论】:

      【解决方案3】:

      这是有趣的事情 - 服务器上的相同代码以更可预测的方式运行,我可能仍然有一些丢失的图像,但现在它就像平均 30-40 中的 1 个与 1 个在我当地的环境中每 5 个。 由于这些请求是异步的,它是否与运行它的机器的实际 CPU 有关,与我那可怜的笔记本电脑相比,服务器更适合处理多个请求?

      无论哪种方式我都修改了代码,所以此时不​​涉及调整大小,处理程序代码只是获取调整大小的图像,此时一切都很好。

      感谢大家的投入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多