创建缩略图和减小图片尺寸

8

我有非常大的图像(jpg),想编写一个C#程序来循环遍历文件并将每个图像的大小减少75%。

我尝试了以下代码:

Image thumbNail = image.GetThumbnailImage(800, 600, null, new IntPtr());

但是文件大小仍然很大。

有没有办法创建缩略图并使文件大小更小?


你传递的尺寸是多少,即宽度和高度的值是多少? - dirkgently
我正在创建尺寸为800 x 600的文件。 - leora
5个回答

18
private void CompressAndSaveImage(Image img, string fileName, 
        long quality) {
    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
    img.Save(fileName, GetCodecInfo("image/jpeg"), parameters);
}

private static ImageCodecInfo GetCodecInfo(string mimeType) {
    foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders())
        if (encoder.MimeType == mimeType)
            return encoder;
    throw new ArgumentOutOfRangeException(
        string.Format("'{0}' not supported", mimeType));
}

使用方法:

Image myImg = Image.FromFile(@"C:\Test.jpg");
CompressAndSaveImage(myImg, @"C:\Test2.jpg", 10);

这会将Test.jpg以10的质量进行压缩并保存为Test2.jpg。

编辑:作为扩展方法可能更好:

private static void SaveCompressed(this Image img, string fileName, 
        long quality) {
    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
    img.Save(fileName, GetCodecInfo("image/jpeg"), parameters);
}

用法:

Image myImg = Image.FromFile(@"C:\Test.jpg");
myImg.SaveCompressed(@"C:\Test2.jpg", 10);

你能让这个函数返回一个Image类型吗?因为我需要保持特定的接口。 - leora
当文件保存时,压缩会发生。您仍然可以使用GetThumbnailImage代码,但是不要调用Image.Save,而应该调用Image.SaveCompressed。据我所知,您无法直接压缩图像对象然后返回它。 - David Brown
你不需要将其保存在文件中,因为你可以将其保存在内存流中,并从内存流中重新创建位图,之后丢弃该流。这样,你可以返回“Image”,同时减小其大小。 - Paulo Santos
嗨David,我运行了你粘贴的代码,但它给出了一个"参数无效"(ArgumentException)的错误。有什么想法错在哪里吗?我使用的是你上面的完全一样的代码! - Storm
好的,找到了罪魁祸首,我需要将10作为10L传递。 - Storm
@DavidBrown,这个方法适用于所有像*.tif这样的图像格式吗? - Behzad

2

ImageMagick是一个命令行工具,非常强大,可用于图像处理。我曾经使用它来调整大小较大的图片并创建缩略图,特别是在源图片的长宽比未知或不可靠的情况下。ImageMagick可以按照原始图片的长宽比例将图片调整为特定的高度或宽度,并在必要时添加图片周围的空白。总之,它非常强大,是与.NET图像API打交道的良好抽象。要在C#中使用imageMagick命令行工具,建议使用System.Diagnostics.ProcessStartInfo对象,如下所示:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = @"C:\Program Files\ImageMagick-6.5.0-Q16\convert.exe";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.Arguments = string.Format("-size x{0} \"{1}\" -thumbnail 200x140 -background transparent -gravity center -extent 200x140 \"{2}\"", heightToResizeTo, originalTempFileLocation, resizedTempFileLocation);

Process p = new Process();
p.StartInfo = psi;
p.Start();
p.WaitForExit();

使用scale%参数,您可以轻松将图像大小缩小75%。

1

压缩您的图像。对于缩略图,JPEG足够了,因为您不需要高质量。

Image thumbNail = image.GetThumbnailImage(800, 600, null, new IntPtr());

thumbNail.Save(fileName, ImageFormat.Jpeg);

0

GetThumbnailImage的文档中:

如果图像包含嵌入式缩略图,则此方法检索嵌入式缩略图并将其缩放到请求的大小。 如果图像不包含嵌入式缩略图,则此方法通过缩放主图像来创建缩略图像。

我建议您使用较小的宽度和高度值。 请尝试:

// reduce the size of each image by 75% from original 800x600
Image thumbNail = image..GetThumbnailImage(200, 150, null, IntPtr.Zero);

请查看示例代码。

还请阅读文档:

当所请求的缩略图像素为大约120x120像素时,GetThumbnailImage方法可以很好地工作。如果您从具有嵌入式缩略图的图像中请求大型缩略图像(例如300x300),则缩略图像可能会出现明显的质量损失。最好通过调用DrawImage方法来缩放主图片(而不是缩放嵌入式缩略图)。

我认为您可能需要查看缩放API。


0

这个方法对我非常有帮助。图像大小小,保持宽高比。

 ShellFile shellFile = ShellFile.FromFilePath(ImageWithPath); //original image path
 Bitmap shellThumbSmall = shellFile.Thumbnail.ExtraLargeBitmap; //change image size
 shellThumbSmall.Save(ImageWithPathThumbnail, ImageFormat.Jpeg); // new image path and format

这些是必需的

PM> Install-Package WindowsAPICodePack-Core
PM> Install-Package WindowsAPICodePack-Shell

using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接