尝试在不更改文件大小的情况下更改图像 DPI
Trying to change image DPI without changing file size
我有以下更改图像 DPI 的代码:
public void changeDPI(string imagePathSource,string imagePathDestination,float DPIx,float DPIy)
{
Bitmap bitmap = new Bitmap(imagePathSource);
Bitmap newBitmap = new Bitmap(bitmap);
newBitmap.SetResolution(DPIx,DPIy);
newBitmap.Save(imagePathDestination);
}
但是,这最终会改变文件的内存大小。示例测试图像从 267 KB 开始,文件的 newBitmap
版本最终为 1.51 MB。如何在不更改文件大小的情况下更改 DPI?
我认为你必须指明输出文件的格式,才能保存为 JPEG 等压缩图像格式。
newBitmap.Save(imagePathDestination, System.Drawing.Imaging.ImageFormat.Jpeg);
你为什么要用它制作新的位图?将图像转换为 32bpp ARGB,并失去与原始加载数据的连接。
原始加载图像的文件格式在 RawFormat
属性 中可用。所以只需将原始位图的分辨率设置为新的分辨率,然后使用 bitmap.RawFormat
:
将其保存到新路径
public void changeDPI(String imagePathSource, String imagePathDestination, Single dpiX, Single dpiY)
{
using (Bitmap bitmap = new Bitmap(imagePathSource))
{
bitmap.SetResolution(dpiX, dpiY);
bitmap.Save(imagePathDestination, bitmap.RawFormat);
}
}
我相信这样,它甚至不会重新压缩实际图像内容,这意味着您不会因重新应用 jpeg 压缩而进一步降低质量。
此外,请务必始终对图像对象调用 Dispose()
,或在 using
块中使用它们。它们是由非托管源(GDI+ 对象)支持的对象,因此您必须小心,否则它们会污染您的程序内存,并锁定您打开的文件。
关于锁定文件的说明,如果您为 imagePathSource
和 imagePathDestination
提供相同的路径,您将收到关于此的错误。要解决这个问题,请提前从图像中读取字节,然后使用 MemoryStream 加载图像:
public void changeDPI(String imagePathSource, String imagePathDestination, Single dpiX, Single dpiY)
{
Byte[] fileData = File.ReadAllbytes(imagePathSource);
using (MemoryStream ms = new MemoryStream(fileData))
using (Bitmap loadedImage = new Bitmap(ms))
{
bitmap.SetResolution(dpiX, dpiY);
bitmap.Save(imagePathDestination, bitmap.RawFormat);
}
}
我有以下更改图像 DPI 的代码:
public void changeDPI(string imagePathSource,string imagePathDestination,float DPIx,float DPIy)
{
Bitmap bitmap = new Bitmap(imagePathSource);
Bitmap newBitmap = new Bitmap(bitmap);
newBitmap.SetResolution(DPIx,DPIy);
newBitmap.Save(imagePathDestination);
}
但是,这最终会改变文件的内存大小。示例测试图像从 267 KB 开始,文件的 newBitmap
版本最终为 1.51 MB。如何在不更改文件大小的情况下更改 DPI?
我认为你必须指明输出文件的格式,才能保存为 JPEG 等压缩图像格式。
newBitmap.Save(imagePathDestination, System.Drawing.Imaging.ImageFormat.Jpeg);
你为什么要用它制作新的位图?将图像转换为 32bpp ARGB,并失去与原始加载数据的连接。
原始加载图像的文件格式在 RawFormat
属性 中可用。所以只需将原始位图的分辨率设置为新的分辨率,然后使用 bitmap.RawFormat
:
public void changeDPI(String imagePathSource, String imagePathDestination, Single dpiX, Single dpiY)
{
using (Bitmap bitmap = new Bitmap(imagePathSource))
{
bitmap.SetResolution(dpiX, dpiY);
bitmap.Save(imagePathDestination, bitmap.RawFormat);
}
}
我相信这样,它甚至不会重新压缩实际图像内容,这意味着您不会因重新应用 jpeg 压缩而进一步降低质量。
此外,请务必始终对图像对象调用 Dispose()
,或在 using
块中使用它们。它们是由非托管源(GDI+ 对象)支持的对象,因此您必须小心,否则它们会污染您的程序内存,并锁定您打开的文件。
关于锁定文件的说明,如果您为 imagePathSource
和 imagePathDestination
提供相同的路径,您将收到关于此的错误。要解决这个问题,请提前从图像中读取字节,然后使用 MemoryStream 加载图像:
public void changeDPI(String imagePathSource, String imagePathDestination, Single dpiX, Single dpiY)
{
Byte[] fileData = File.ReadAllbytes(imagePathSource);
using (MemoryStream ms = new MemoryStream(fileData))
using (Bitmap loadedImage = new Bitmap(ms))
{
bitmap.SetResolution(dpiX, dpiY);
bitmap.Save(imagePathDestination, bitmap.RawFormat);
}
}