[英]C# Image Resizing - Losing EXIF
是的...我已經看到了與此問題相關的其他帖子,是的...我已經開始搜索它了。
但到目前為止,我無法得到我需要的結果。
我正在加載以300 dpi拍攝的大圖像,我需要調整它的大小。
我知道......我知道...... dpi是相對的,並不重要......重要的是像素尺寸:
DPI基本上是在打印圖像時對應於一英寸的像素數,而不是在屏幕上查看時的像素數。 因此,通過增加圖像的DPI,您不會增加屏幕上圖像的大小。 您只能提高打印質量。
盡管存儲在圖像EXIF中的DPI信息有些無用,但它卻給我帶來了麻煩。
我正在調整大小的圖像正在丟失原始exif信息,包括水平和垂直分辨率(dpi),因此它默認保存為96 dpi。 可能的原因是只有JPEG和其他格式可以保存元數據信息。
最終圖像結果應如下所示:275x375 at 300dpi而不是這樣:275x375 at 96dpi
您可以爭辯說它們是相同的,我同意,但是我們有一個用於加載這些圖像的corel繪制腳本,並且由於此dpi信息不同,因此它會在文檔上放置不同的大小。
這是我用於調整大小的內容:
public System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
{
Bitmap result = new Bitmap(width, height);
// set the resolutions the same to avoid cropping due to resolution differences
result.SetResolution(image.HorizontalResolution, image.VerticalResolution);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the image into the target bitmap
graphics.DrawImage(image, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}
這項工作做得很好,但丟失了EXIF信息。
將SetResolution設置為SetResolution(300,300)不起作用!
我查看了閱讀和更改圖像的EXIF信息,我嘗試過:
public void setImageDpi(string Filename, string NewRes)
{
Image Pic;
PropertyItem[] PropertyItems;
byte[] bDescription = new Byte[NewRes.Length];
int i;
string FilenameTemp;
System.Drawing.Imaging.Encoder Enc = System.Drawing.Imaging.Encoder.Transformation;
EncoderParameters EncParms = new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");
// copy description into byte array
for (i = 0; i < NewRes.Length; i++) bDescription[i] = (byte)NewRes[i];
// load the image to change
Pic = Image.FromFile(Filename);
foreach (PropertyItem item in Pic.PropertyItems)
{
if (item.Id == 282 || item.Id == 283)
{
PropertyItem myProperty = item;
myProperty.Value = bDescription;
myProperty.Type = 2;
myProperty.Len = NewRes.Length;
Pic.SetPropertyItem(item);
Console.WriteLine(item.Type);
}
}
// we cannot store in the same image, so use a temporary image instead
FilenameTemp = Filename + ".temp";
// for lossless rewriting must rotate the image by 90 degrees!
EncParm = new EncoderParameter(Enc, (long)EncoderValue.TransformRotate90);
EncParms.Param[0] = EncParm;
// now write the rotated image with new description
Pic.Save(FilenameTemp, CodecInfo, EncParms);
// for computers with low memory and large pictures: release memory now
Pic.Dispose();
Pic = null;
GC.Collect();
// delete the original file, will be replaced later
System.IO.File.Delete(Filename);
// now must rotate back the written picture
Pic = Image.FromFile(FilenameTemp);
EncParm = new EncoderParameter(Enc, (long)EncoderValue.TransformRotate270);
EncParms.Param[0] = EncParm;
Pic.Save(Filename, CodecInfo, EncParms);
// release memory now
Pic.Dispose();
Pic = null;
GC.Collect();
// delete the temporary picture
System.IO.File.Delete(FilenameTemp);
}
那也行不通。
我嘗試在此過程的后期查找和更改DPI(282和283)的EXIF信息:
Encoding _Encoding = Encoding.UTF8;
Image theImage = Image.FromFile("somepath");
PropertyItem propItem282 = theImage.GetPropertyItem(282);
propItem282.Value = _Encoding.GetBytes("300" + '\0');
theImage.SetPropertyItem(propItem282);
PropertyItem propItem283 = theImage.GetPropertyItem(283);
propItem283.Value = _Encoding.GetBytes("300" + '\0');
theImage.SetPropertyItem(propItem283);
theImage.Save("somepath");
但程序崩潰說無法找到財產。
如果該屬性不存在,顯然我無法添加它:
PropertyItem不能用作獨立對象。 PropertyItem對象旨在由派生自Image的類使用。 PropertyItem對象用於檢索和更改現有圖像文件的元數據,而不是創建元數據。 因此,PropertyItem類沒有已定義的Public構造函數,您無法創建PropertyItem對象的實例。
我被困了......我需要的是一張dpi設置為300的調整大小的圖像, 它不應該那么難。
任何幫助非常感謝。 謝謝
以下代碼對我有用:
const string InputFileName = "test_input.jpg";
const string OutputFileName = "test_output.jpg";
var newSize = new Size(640, 480);
using (var bmpInput = Image.FromFile(InputFileName))
{
using (var bmpOutput = new Bitmap(bmpInput, newSize))
{
foreach (var id in bmpInput.PropertyIdList)
bmpOutput.SetPropertyItem(bmpInput.GetPropertyItem(id));
bmpOutput.SetResolution(300.0f, 300.0f);
bmpOutput.Save(OutputFileName, ImageFormat.Jpeg);
}
}
當我檢查輸出文件時,我可以看到EXIF數據,DPI已經變為300。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.