C#简单图像调整:文件大小未缩小

3
我有一个关于下面代码的问题。我以下面的代码成功地运行了整个目录,并将图片的分辨率设置为更小的大小。然而,文件大小没有变化。例如,一张2400x1800像素且文件大小为1.5MB的图像被缩放为800x600像素,但是800x600像素的图片仍然是1.5MB的文件大小。我认为我可能需要显式压缩图片,但我不确定。有任何想法吗?
private void Form1_Load(object sender, EventArgs e)
        {
            string[] files = null;
            int count = 0;
            files = System.IO.Directory.GetFiles(@"C:\Users\..\..\ChristmasPicsResized");
            foreach (string file in files)
            {
                System.Drawing.Bitmap bmp = System.Drawing.Bipmap.FromFile(file);

                ResizeBitmap(bmp, 807, 605).Save(
                     @"C:\users\..\..\TempPicHold\Pic" + count.ToString() + ".jpg");
                count++;
            }
        }
        public Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
        {
            Bitmap result = new Bitmap(nWidth, nHeight);
            using (Graphics g = Graphics.FromImage((Image)result))
                g.DrawImage(b, 0, 0, nWidth, nHeight);
            return result;
        }
6个回答

9

找到了问题。感谢@yetapb展示了一份更干净的代码版本,但仍然没有起作用。问题的答案是我需要明确指定图像保存的文件类型。我猜测因为我没有显式地指定图像格式,所以图像压缩没有得到相应的处理。一个位图只是以较小的分辨率保存,并带有'.jpg'后缀,但没有得到相应的压缩。以下代码现在可以正常工作。

            files = System.IO.Directory.GetFiles(@"C:\PicFolder");
            for (string file in files)
            {
            Bitmap tempBmp = new Bitmap(file);
            Bitmap bmp = new Bitmap(tempBmp, 807, 605);

            bmp.Save(
            @"C:\NewPicFolder\Pic" + count + ".jpg",
            System.Drawing.Imaging.ImageFormat.Jpeg);
            count++;
            }

2
此外,请查看需要避免的图像调整陷阱。目前,您正在泄漏GDI句柄、内存,并生成低质量图像。 - Lilith River
为何不使用一个避免你遇到的所有GDI错误的库呢?http://imageresizing.net库是免费、开源、得到支持和有很好的文档。它还有一个一行API,大约需要1秒钟就能理解。 - Lilith River

2

您需要设置图形对象的某些属性来改变图像的质量。

graphics.CompositingQuality = CompositingQuality.HighSpeed; 
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(photo, 0, 0, width, height);

在保存文件时,您还可以设置不同的压缩编码或将其保存为不同的格式。


同时,还有以下代码:graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - vapcguy

2

对于位图不确定,但是对于其他图片,您可以指定不同的压缩编码器。有关详细信息,请参阅MSDN 此处


0

我做了一些修改,以下代码按预期减小了文件大小(对我而言)。

private void Form1_Load(object sender, EventArgs e)
{
    string[] files = null;
    int count = 0;
    files = System.IO.Directory.GetFiles(@"C:\Users\..\..\ChristmasPicsResized");
    foreach (string file in files)
    {
        Bitmap bmp = new Bitmap( file );
        new Bitmap( bmp, 807, 605 ).Save(
                   @"C:\users\..\..\TempPicHold\Pic" + count.ToString() + ".jpg");
        count++;   
    }
}

}


那么,你是创建一个新的位图,而不是执行 System.Drawing.Bitmap bmp = System.Drawing.Bipmap.FromFile(file); 吗?但是,这个版本仍然存在将 .jpg 添加到位图文件末尾的问题。OP 似乎想要转换,而不仅仅是重命名为 .jpg - vapcguy
看了我写的和原帖作者写的(6年前!),我可以看出我只是编辑了他的代码,使文件大小减小了(对我来说)。他的问题从未明确表示想要转换为JPEG格式,但他自己的回答却是这样的。 - µBio

0
 private void button4_Click(object sender, EventArgs e)
  {
            String[] files;
            int count = 0;
            files = System.IO.Directory.GetFiles(@"C:/dataset");
            foreach (string file in files)
            {
            Bitmap tempBmp = new Bitmap(file);
            Bitmap bmp = new Bitmap(tempBmp, 200, 200);

            bmp.Save(
            @"C:/Newdataset1/" + count + ".jpg",
            System.Drawing.Imaging.ImageFormat.Jpeg);
            count++;
            }  

}


最好能解释一下逻辑。 - Kenneth K.

0
有趣的实现细节:将图像翻转两次,会导致缩略图被丢弃,从而减小文件大小。

result.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); result.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);


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