从缓存中获取位图

发布于 2024-09-28 09:39:46 字数 4623 浏览 0 评论 0原文

每当我尝试获取从上下文缓存的位图时,我都会收到参数异常。位图是从缓存的对象中转换而来的,但其内容已损坏。

异常在

ImageFormat imageFormat = bitmap.RawFormat;

bitmap.RawFormat' 行上引发,抛出了类型为“System.ArgumentException”的异常,

这只是给了我消息“参数无效”。

当我在代码中插入断点时,查看从缓存创建的位图,所有属性都会报告相同的异常。

这是我的处理程序的流程请求......

    /// <summary>
    /// Processes the image request.
    /// </summary>
    /// <param name="context">The httpContext handling the request.</param>
    public void ProcessRequest(HttpContext context)
    {
        //write your handler implementation here.
        if (!string.IsNullOrEmpty(context.Request.QueryString["file"]))
        {
            string file = context.Request.QueryString["file"];
            bool thumbnail = Convert.ToBoolean(context.Request.QueryString["thumb"]);
            // Throw in some code to check width and height.
            int width = Convert.ToInt32(context.Request.QueryString["width"]);
            int height = Convert.ToInt32(context.Request.QueryString["height"]);

            // Store our context key.
            string key = file;

            // Strip away our cache data value.
            file = file.Substring(0, file.LastIndexOf("_", StringComparison.OrdinalIgnoreCase));

            OnServing(file);

            try
            {
                //Check the cache for a file.
                Bitmap bitmap = (Bitmap)context.Cache[key];
                if (bitmap != null)
                {
                    ImageFormat imageFormat = bitmap.RawFormat;
                    // We've found something so lets serve that.
                    using (MemoryStream ms = new MemoryStream())
                    {
                        bitmap.Save(ms, imageFormat);
                        context.Response.BinaryWrite(ms.ToArray());
                    }

                }
                else
                {
                    // Nothing found lets create a file.
                    // Lock the file to prevent access errors.
                    lock (this.syncRoot)
                    {
                        string path = HostingEnvironment.MapPath(String.Format("~/Images/{0}", file));
                        FileInfo fi = new FileInfo(path);
                        if (fi.Exists)
                        {
                            using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
                            {
                                ImageFormat imageFormat = img.RawFormat;
                                if (thumbnail)
                                {
                                    ImageEditor imageEditor = new ImageEditor(img);
                                    Size size = new Size(width, height);
                                    imageEditor.Resize(size, true);
                                    imageEditor.FixGifColors();

                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        imageEditor.Image.Save(ms, imageFormat);

                                        // Add the file to the cache.
                                        context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
                                        imageEditor.Dispose();
                                        context.Response.BinaryWrite(ms.ToArray());
                                    }
                                }
                                else
                                {
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        img.Save(ms, imageFormat);

                                        // Add the file to the cache.
                                        context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
                                        context.Response.BinaryWrite(ms.ToArray());
                                    }
                                }
                                OnServed(file);
                            }
                        }
                        else
                        {
                            OnBadRequest(file);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
                // OnBadRequest(ex.Message);
                // return a default empty file here.                    
            }

        }

    }

任何帮助将不胜感激。

Whenever I try to get a bitmap I have cached from the context I am getting an argument exception. The bitmap is cast from the cached object but it's contents are corrupted.

The exception is thrown on the line

ImageFormat imageFormat = bitmap.RawFormat;

bitmap.RawFormat' threw an exception of type 'System.ArgumentException'

Which just gives me the message 'Parameter not valid.'

When I stick a breakpoint in the code look at the bitmap created from the cache all the properties report back the same exception.

Here's the process request from my handler....

    /// <summary>
    /// Processes the image request.
    /// </summary>
    /// <param name="context">The httpContext handling the request.</param>
    public void ProcessRequest(HttpContext context)
    {
        //write your handler implementation here.
        if (!string.IsNullOrEmpty(context.Request.QueryString["file"]))
        {
            string file = context.Request.QueryString["file"];
            bool thumbnail = Convert.ToBoolean(context.Request.QueryString["thumb"]);
            // Throw in some code to check width and height.
            int width = Convert.ToInt32(context.Request.QueryString["width"]);
            int height = Convert.ToInt32(context.Request.QueryString["height"]);

            // Store our context key.
            string key = file;

            // Strip away our cache data value.
            file = file.Substring(0, file.LastIndexOf("_", StringComparison.OrdinalIgnoreCase));

            OnServing(file);

            try
            {
                //Check the cache for a file.
                Bitmap bitmap = (Bitmap)context.Cache[key];
                if (bitmap != null)
                {
                    ImageFormat imageFormat = bitmap.RawFormat;
                    // We've found something so lets serve that.
                    using (MemoryStream ms = new MemoryStream())
                    {
                        bitmap.Save(ms, imageFormat);
                        context.Response.BinaryWrite(ms.ToArray());
                    }

                }
                else
                {
                    // Nothing found lets create a file.
                    // Lock the file to prevent access errors.
                    lock (this.syncRoot)
                    {
                        string path = HostingEnvironment.MapPath(String.Format("~/Images/{0}", file));
                        FileInfo fi = new FileInfo(path);
                        if (fi.Exists)
                        {
                            using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
                            {
                                ImageFormat imageFormat = img.RawFormat;
                                if (thumbnail)
                                {
                                    ImageEditor imageEditor = new ImageEditor(img);
                                    Size size = new Size(width, height);
                                    imageEditor.Resize(size, true);
                                    imageEditor.FixGifColors();

                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        imageEditor.Image.Save(ms, imageFormat);

                                        // Add the file to the cache.
                                        context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
                                        imageEditor.Dispose();
                                        context.Response.BinaryWrite(ms.ToArray());
                                    }
                                }
                                else
                                {
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        img.Save(ms, imageFormat);

                                        // Add the file to the cache.
                                        context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
                                        context.Response.BinaryWrite(ms.ToArray());
                                    }
                                }
                                OnServed(file);
                            }
                        }
                        else
                        {
                            OnBadRequest(file);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
                // OnBadRequest(ex.Message);
                // return a default empty file here.                    
            }

        }

    }

Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

宛菡 2024-10-05 09:39:46

我建议不要持有资源超过其需要的时间。

至于上面的代码,问题在于,当您获取保存的图像时,您并没有创建新的位图 - 您正在从缓存中检索现有的位图,该位图可能已经被处理掉了。尝试使用以下内容代替:

// When saving to the cache, use a MemoryStream to save off the bitmap as an array of bytes
using (MemoryStream ms = new MemoryStream()) {
    bitmap.Save(ms, bitmap.RawFormat);
    context.Cache.Insert(key, (byte[])ms.ToArray(), ...
    ...
}

...

// When retrieving, create a new Bitmap based on the bytes retrieved from the cached array
if (context.Cache[key] != null) {
    using (MemoryStream ms = new MemoryStream((byte[])context.Cache[key])) {
        using (Bitmap bmp = new Bitmap(ms)) {
            bmp.Save(context.Response.OutputStream ...
...

I can recommend not holding onto resources for longer than they're needed.

As for the code above, the issue is that you aren't creating a new bitmap when you get a saved image - you're retrieving an existing one from the cache, which has probably already been disposed of. Try using the following instead:

// When saving to the cache, use a MemoryStream to save off the bitmap as an array of bytes
using (MemoryStream ms = new MemoryStream()) {
    bitmap.Save(ms, bitmap.RawFormat);
    context.Cache.Insert(key, (byte[])ms.ToArray(), ...
    ...
}

...

// When retrieving, create a new Bitmap based on the bytes retrieved from the cached array
if (context.Cache[key] != null) {
    using (MemoryStream ms = new MemoryStream((byte[])context.Cache[key])) {
        using (Bitmap bmp = new Bitmap(ms)) {
            bmp.Save(context.Response.OutputStream ...
...
云裳 2024-10-05 09:39:46

当您缓存图像对象时,您将在 using 块内执行此操作:

using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
{
    // ... lots of code

    // Add the file to the cache.
    context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));

    // ... other code
}

在此 using 块的末尾,您的位图将被释放。因此您不能再次使用它。如果您想再次使用缓存中的位图,则需要停止处理该位图。

然而,考虑到您只想再次返回相同的图像(如果已缓存),则仅缓存 MemoryStream 可能会更简单、更高效 - 这不会受到任何不可见的 GDI+ 关系,并且可以在几乎不进行缓存处理的情况下返回打。

When you cache the image object you are doing so inside a using block:

using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
{
    // ... lots of code

    // Add the file to the cache.
    context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));

    // ... other code
}

At the end of this using block, your bitmap will be disposed. Therefore you can't use it again. You need to stop disposing the bitmap if you want to use it again from the cache.

However, given that you just want to return the same image again if it's cached, it might be simpler and more efficient to just cache the MemoryStream - this doesn't suffer any invisible GDI+ ties and can be returned with almost no processing on a cache hit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文