我试图为我的网站创建一个图像处理程序,基本调整大小,旋转和裁剪工作,并在网站上显示正常但是我试图通过将文件保存在/chached/filename.png
中来添加缓存到处理程序但是在我添加缓存后,图像处理程序返回错误的图像。例如,我有一个项目列表页面,其中调整大小的项目图像以表格视图显示,但前4个项目显示为具有相同的图像,然后接下来的4个不同的图像,但所有相同,等等。
我感觉这是由response.outputstream
引起的,但我不确定,因为看起来没有足够的时间来完成下一个图像的第一个图像。
以防万一,完整代码可在此处获取:http://pastebin.com/BNyDfqPy
我的流程请求方法如下:
public void ProcessRequest(HttpContext context)
{
// Settings and locations
appPath = HttpContext.Current.Request.PhysicalApplicationPath;
location = context.Request.QueryString["image"];
cacheLocation = Path.GetDirectoryName(appPath + location) + "/Cached/";
// Input/Output
Bitmap bitOutput;
Bitmap bitInput = GetImage(context);
if (cacheAvailable)
{
bitOutput = bitInput;
}
else
{
try
{
Boolean crop = false;
if (context.Request["type"] == "crop")
{
crop = true;
}
bitInput = RotateFlipImage(context, bitInput);
if (hasSetSize)
{
Int32 x = String.IsNullOrEmpty(context.Request["x"]) ? 0 : Int32.Parse(context.Request["x"]);
Int32 y = String.IsNullOrEmpty(context.Request["y"]) ? 0 : Int32.Parse(context.Request["y"]);
bitOutput = ResizeImage(bitInput, _width, _height, crop, x, y);
bitOutput.Save(cacheLocation + cacheKey + ".png", System.Drawing.Imaging.ImageFormat.Png);
}
else
{
throw new Exception();
}
}
catch (Exception)
{
bitOutput = bitInput;
}
}
context.Response.Clear();
context.Response.Cache.SetNoStore();
context.Response.ContentType = "image/png";
using (MemoryStream ms = new MemoryStream())
{
bitOutput.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.WriteTo(context.Response.OutputStream);
}
//bitOutput.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);
bitOutput.Dispose();
bitInput.Dispose();
context.Response.Flush();
return;
}
我用这个得到了图像:
public Bitmap GetImage(HttpContext context)
{
// Get location
Bitmap bitOutput = null;
try
{
if (!String.IsNullOrEmpty(location))
{
Image image = Image.FromFile(appPath + location);
bitOutput = new Bitmap(image);
hasSetSize = SetHeightWidth(context, bitOutput);
if (!System.IO.Directory.Exists(cacheLocation))
{
System.IO.Directory.CreateDirectory(cacheLocation);
}
// Generate cache key
cacheKey = "imagehandler_" + _width + "x" + _height + "_" + context.Request["RotateFlip"] + context.Request["type"];
if (File.Exists(cacheLocation + cacheKey + ".png"))
{
image = Image.FromFile(cacheLocation + cacheKey + ".png");
bitOutput = new Bitmap(image);
cacheAvailable = true;
}
}
else
{
throw new Exception("Can't load original or save to cache, check directory permissions!");
}
}
catch (Exception)
{
Image image = Image.FromFile(appPath + noImageUrl);
bitOutput = new Bitmap(image);
}
return bitOutput;
}
我还设置isReusable
如下:
public bool IsReusable
{
get
{
return false;
}
}
输出看起来像下面的图像,每个项目都有不同的图像集,但它们要么显示与上一个/下一个图像相同的图像,它是自己的图像(这是我想要的)或占位符图像:
答案 0 :(得分:2)
正如我看到代码你可能使用cacheAvailable
的静态变量而after设置为true后,下次调用时不会返回false。
因此,请检查何时将cacheAvailable
false作为每个请求的默认值。
答案 1 :(得分:0)
首先,除非您真的希望您的处理程序能够反复使用同一个实例,否则IsReusable
将返回false。
如果您不想这样做,请删除cacheAvailable
班级变量,更改此内容:
// Input/Output
Bitmap bitOutput;
Bitmap bitInput = GetImage(context);
对此:
// Input/Output
Bitmap bitOutput;
bool cacheAvailable;
Bitmap bitInput = GetImage(context, out cacheAvailable);
修改GetImage
看起来像这样
public Bitmap GetImage(HttpContext context, out bool cacheAvailable)
{
// Get location
Bitmap bitOutput = null;
cacheAvailable = false;
try
{
if (!String.IsNullOrEmpty(location))
{
Image image = Image.FromFile(appPath + location);
bitOutput = new Bitmap(image);
hasSetSize = SetHeightWidth(context, bitOutput);
if (!System.IO.Directory.Exists(cacheLocation))
{
System.IO.Directory.CreateDirectory(cacheLocation);
}
// Generate cache key
cacheKey = "imagehandler_" + _width + "x" + _height + "_" + context.Request["RotateFlip"] + context.Request["type"];
if (File.Exists(cacheLocation + cacheKey + ".png"))
{
image = Image.FromFile(cacheLocation + cacheKey + ".png");
bitOutput = new Bitmap(image);
cacheAvailable = true;
}
}
else
{
throw new Exception("Can't load original or save to cache, check directory permissions!");
}
}
catch (Exception)
{
Image image = Image.FromFile(appPath + noImageUrl);
bitOutput = new Bitmap(image);
}
return bitOutput;
}