@functions{
public void GetThumbnailView(string originalImagePath, int height, int width)
{
//Consider Image is stored at path like "ProductImage\\Product1.jpg"
//Now we have created one another folder ProductThumbnail to store thumbnail image of product.
//So let name of image be same, just change the FolderName while storing image.
string thumbnailImagePath = originalImagePath;
originalImagePath = originalImagePath.Replace("thumb_", "");
//If thumbnail Image is not available, generate it.
if (!System.IO.File.Exists(Server.MapPath(thumbnailImagePath)))
{
System.Drawing.Image imThumbnailImage;
System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(Server.MapPath(originalImagePath));
double originalWidth = OriginalImage.Width;
double originalHeight = OriginalImage.Height;
double ratioX = (double)width / (double)originalWidth;
double ratioY = (double)height / (double)originalHeight;
double ratio = ratioX < ratioY ? ratioX : ratioY; // use whichever multiplier is smaller
// now we can get the new height and width
int newHeight = Convert.ToInt32(originalHeight * ratio);
int newWidth = Convert.ToInt32(originalWidth * ratio);
imThumbnailImage = OriginalImage.GetThumbnailImage(newWidth, newHeight,
new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
imThumbnailImage.Save(Server.MapPath(thumbnailImagePath), System.Drawing.Imaging.ImageFormat.Jpeg);
imThumbnailImage.Dispose();
OriginalImage.Dispose();
}
}
public bool ThumbnailCallback() { return false; }
}
在另一个stackowerflow问题中,我发现这个代码并且非常喜欢它,但在使用它时,在创建缩略图时出现了问题,如下所示:
2>'/'应用程序中的服务器错误。内存不足。描述:期间发生了未处理的异常 执行当前的Web请求。请查看堆栈 跟踪以获取有关错误及其来源的更多信息 代码。
异常详细信息:System.OutOfMemoryException:内存不足。
来源错误:
第199行:{
第200行:System.Drawing.Image imThumbnailImage;
第201行:System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(使用Server.Mappath(originalImagePath.ToString()));
第202行:
第203行:double originalWidth = OriginalImage.Width;
源文件:c:\ Inetpub \ wwwroot \ Lokal \ Views \ Stok \ SatisRaporu.cshtml
行:201
我对这个问题的好奇心让我进入了异常细节并看到了这一点:
//
// Summary:
// Creates an System.Drawing.Image from the specified file.
//
// Parameters:
// filename:
// A string that contains the name of the file from which to create the System.Drawing.Image.
//
// Returns:
// The System.Drawing.Image this method creates.
//
// Exceptions:
// System.OutOfMemoryException:
// The file does not have a valid image format.-or- GDI+ does not support the
// pixel format of the file.
//
// System.IO.FileNotFoundException:
// The specified file does not exist.
//
// System.ArgumentException:
// filename is a System.Uri.
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Image FromFile(string filename);
但是我在该文件夹中的所有图片都有“.jpg”扩展名,因此对我来说似乎很奇怪。 如果我不能从“.jpg”创建缩略图我还能做什么?
我实际上想知道是否有其他人在“.jpg”文件上尝试过此操作并遇到问题?如果没有问题我可能做错了什么?
一点注意事项:我在使用剃刀语法的视图中执行此操作。我对c#语言有一点了解,并且每天都在提高我对它的了解。
修改:
我如何称呼该功能:
GetThumbnailView("../pics/thumb_" + (("0000000" + stocks.stockcode).Substring(("0000000" + stocks.stockcode).Length - 7, 7)) + ".jpg", 200, 200);
答案 0 :(得分:3)
我工作的网站使用WPF API而不是GDI +生成缩略图。您需要为项目添加两个引用以启用此功能:WindowsBase,PresentationFramework和PresentationCore。以下是如何使用代码的基本示例:
try
{
using (var input = File.Open(inputFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var thumb = File.Open(thumbFilename, FileMode.Create, FileAccess.Write, FileShare.None))
{
Thumbnail(input, thumb, 200, 100);
}
}
catch (MyException)
{
File.Delete(thumbFilename);
}
这使缩略图适合200x100矩形,同时保留纵横比。
(真正的网站不像上面那样。我们实际做的是尝试在文件上传POST处理程序中生成最小的缩略图。我们使用内存流来保存生成的缩略图。如果缩略图可以正确生成,我们保存上传和小缩略图,否则我们会向客户端返回错误响应。其他缩略图大小即时生成并缓存。)
这是代码 - 注意我可能在将其转换为可重用的东西时搞砸了一些,但核心位应该都存在。请注意,它将所有缩略图保存为JPEG,但允许多种输入格式,包括JPEG和PNG。这可能对你有用,也可能不对。
private static void Thumbnail(Stream source, Stream destination, int maxWidth, int maxHeight)
{
int width = 0, height = 0;
BitmapFrame frame = null;
try
{
frame = BitmapDecoder.Create(source, BitmapCreateOptions.None, BitmapCacheOption.None).Frames[0];
width = frame.PixelWidth;
height = frame.PixelHeight;
}
catch
{
throw new MyException("The image file is not in any of the supported image formats.");
}
if (width > AbsoluteLargestUploadWidth || height > AbsoluteLargestUploadHeight)
throw new MyException("This image is too large");
try
{
int targetWidth, targetHeight;
ResizeWithAspect(width, height, maxWidth, maxHeight, out targetWidth, out targetHeight);
BitmapFrame targetFrame;
if (frame.PixelWidth == targetWidth && frame.PixelHeight == targetHeight)
targetFrame = frame;
else
{
var group = new DrawingGroup();
RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
group.Children.Add(new ImageDrawing(frame, new Rect(0, 0, targetWidth, targetHeight)));
var targetVisual = new DrawingVisual();
var targetContext = targetVisual.RenderOpen();
targetContext.DrawDrawing(group);
var target = new RenderTargetBitmap(targetWidth, targetHeight, 96, 96, PixelFormats.Default);
targetContext.Close();
target.Render(targetVisual);
targetFrame = BitmapFrame.Create(target);
}
var enc = new JpegBitmapEncoder();
enc.Frames.Add(targetFrame);
enc.QualityLevel = 80;
enc.Save(destination);
}
catch
{
throw new MyException("The image file appears to be corrupt.");
}
}
/// <summary>Generic helper to compute width/height that fit into specified maxima while preserving aspect ratio.</summary>
public static void ResizeWithAspect(int origWidth, int origHeight, int maxWidth, int maxHeight, out int sizedWidth, out int sizedHeight)
{
if (origWidth < maxWidth && origHeight < maxHeight)
{
sizedWidth = origWidth;
sizedHeight = origHeight;
return;
}
sizedWidth = maxWidth;
sizedHeight = (int) ((double) origHeight / origWidth * sizedWidth + 0.5);
if (sizedHeight > maxHeight)
{
sizedHeight = maxHeight;
sizedWidth = (int) ((double) origWidth / origHeight * sizedHeight + 0.5);
}
}
答案 1 :(得分:1)
文件扩展名无关紧要,重要的是图像的实际字节数。很可能其中一个jpgs已损坏。您应该在每个文件的基础上捕获OutOfMemory异常并适当地处理它。
由于您尝试生成缩略图,我建议您在无法生成缩略图时使用默认图像。例如,当图像损坏或丢失时,大多数Web浏览器都使用带有红色X的小盒子。
另见: SO#6506089 SO#1108607 SO#1644108 SO#9237457
对于那些为什么抛出OutOfMemoryException感到好奇的人,请看这个问题的答案: Is there a reason Image.FromFile throws an OutOfMemoryException for an invalid image format?