使用C#创建缩略图 [英] Creating thumbnail images with C#

查看:143
本文介绍了使用C#创建缩略图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@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问题中,我找到了这段代码并非常喜欢它,但是在使用它时,在创建缩略图时出现了问题,如下所示:

in another stackowerflow question i found this code and really liked it but while using it there was a problem occured while creating the thumbnail images as shown below:

"/"应用程序中的服务器错误.

内存不足.说明:在处理期间发生未处理的异常 当前Web请求的执行.请检查堆栈 跟踪以获取有关该错误及其起源的更多信息. 代码.

Server Error in '/' Application.

Out of memory. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

异常详细信息:System.OutOfMemoryException:内存不足.

Exception Details: System.OutOfMemoryException: Out of memory.

源错误:

第199行:{

第200行:System.Drawing.Image imThumbnailImage;

Line 200: System.Drawing.Image imThumbnailImage;

第201行:System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(Server.MapPath(originalImagePath.ToString()));

Line 201: System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(Server.MapPath(originalImagePath.ToString()));

第202行:

第203行:double originalWidth = OriginalImage.Width;

Line 203: double originalWidth = OriginalImage.Width;

源文件:c:\ Inetpub \ wwwroot \ Lokal \ Views \ Stok \ SatisRaporu.cshtml
行:201

Source File: c:\Inetpub\wwwroot\Lokal\Views\Stok\SatisRaporu.cshtml
Line: 201

我对这个问题的好奇心使我进入了异常详细信息,并看到了:

my curiosity about this issue got me into the exception details and seen this :

    //
    // 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"创建缩略图,我还能做什么?

but all my pictures in that folder has ".jpg" extention so it seems wierd to me. if im not gonna be able to create thumbnails from ".jpg" what else i can do?

我实际上想了解是否有人在".jpg"文件上尝试过此操作,是否遇到了问题?如果没有问题发生,那我可能做错了什么?

I actually want to learn about if anyone else tried this on ".jpg" files and got a problem with it? and If no problem occured what i might be doing wrong?

一些注意事项:我是在使用剃刀语法的视图中执行此操作的.我对c#语言有所了解,并且每天都会提高对c#语言的了解.

A little note: I do this in a view using razor syntax. I know a little about c# language and improving my knowledge about it everyday.

我如何调用该函数:

GetThumbnailView("../pics/thumb_" + (("0000000" + stocks.stockcode).Substring(("0000000" + stocks.stockcode).Length - 7, 7)) + ".jpg", 200, 200);

推荐答案

我正在研究的网站使用WPF API而非GDI +生成其缩略图.您需要为项目添加两个引用以启用此功能:WindowsBase,PresentationFramework和PresentationCore.这是一个代码用法的基本示例:

A website I work on generates its thumbnails using the WPF APIs instead of GDI+. You need to add two references to your project to enable this: WindowsBase, PresentationFramework and PresentationCore. Here’s a basic example of how the code might be used:

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的矩形,同时保留宽高比.

This fits the thumbnail into a 200x100 rectangle, while preserving aspect ratio.

(真实的网站并没有像上面那样做.我们实际要做的是尝试在文件上传POST处理程序中生成最小的缩略图.我们使用内存流来保存生成的缩略图.如果缩略图可以要正确生成,我们将保存上传内容和较小的缩略图,否则我们将向客户端返回错误响应.其他缩略图尺寸会即时生成并缓存.)

(The real website doesn’t do it quite like the above. What we actually do is attempt to generate the smallest thumbnail in the file upload POST handler. We use a memory stream to hold the resulting thumbnail. If the thumbnail could be generated correctly, we save the upload and the small thumbnail, otherwise we return an error response to the client. Other thumbnail sizes are generated on the fly and cached.)

这是代码-请注意,在将其转换为可重用的内容时,我可能有些混乱,但是核心部分都应该存在.请注意,它将所有缩略图另存为JPEG,但允许多种输入格式,包括JPEG和PNG.这可能适合您,也可能不适合您.

Here’s the code - note that I may have messed up a bit while transforming this into something reusable, but the core bits should all be there. Note that it saves all thumbnails as JPEG, but allows multiple input formats, including JPEG and PNG. This might or might not be OK for you.

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

这篇关于使用C#创建缩略图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆