从缓存中获取位图

时间:2010-10-18 10:08:32

标签: c# asp.net caching gdi+

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

行抛出异常

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.                    
            }

        }

    }

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

我建议不要长时间保留资源。

至于上面的代码,问题是当你得到一个保存的图像时你没有创建一个新的位图 - 你正在从缓存中检索一个现有的位图,这可能已经被处理掉了。请尝试使用以下内容:

// 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 ...
...

答案 1 :(得分:2)

当您在使用块内缓存图像对象时:

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
}

在此使用块的末尾,您的位图将被丢弃。因此,您无法再次使用它。如果要从缓存中再次使用位图,则需要停止处理位图。

但是,考虑到你只是想在缓存时再次返回相同的图像,只是缓存MemoryStream可能更简单,更有效 - 这不会遭受任何不可见的GDI +关系,并且几乎不需要处理就可以返回在缓存命中。