2010-08-20 108 views
6

我試圖調整大小並保存圖像,這很容易(例如, 請參閱此示例 外部示例不再有效)。保存元數據時調整大小和保存圖像

但是,使用此代碼將從圖像中去除元數據信息。我似乎無法弄清楚如何保存JPEG圖像的元數據。

**編輯:示例代碼**

public static void ResizeMethodThree(string sourceFile, string targetFile) 
    { 
     byte[] baSource = File.ReadAllBytes(sourceFile); 

     PropertyItem[] propertyItems = new Bitmap(sourceFile).PropertyItems; 

     using (Stream streamPhoto = new MemoryStream(baSource)) 
     { 
      BitmapFrame bfPhoto = ReadBitmapFrame(streamPhoto); 
      BitmapMetadata metaData = (BitmapMetadata)bfPhoto.Metadata; 
      int nNewPictureSize = 200; 
      int nWidth = 0; 
      int nHeight = 0; 

      if (bfPhoto.Width > bfPhoto.Height) 
      { 
       nWidth = nNewPictureSize; 
       nHeight = (int)(bfPhoto.Height * nNewPictureSize/bfPhoto.Width); 
      } 
      else 
      { 
       nHeight = nNewPictureSize; 
       nWidth = (int)(bfPhoto.Width * nNewPictureSize/bfPhoto.Height); 
      }   

      BitmapFrame bfResize = ResizeHelper(bfPhoto, nWidth, nHeight, BitmapScalingMode.HighQuality); 

      byte[] baResize = ToByteArray(bfResize); 

      File.WriteAllBytes(targetFile, baResize); 

      Image targetImage = new Bitmap(targetFile); 
      foreach (var propertyItem in propertyItems) 
      { 
       targetImage.SetPropertyItem(propertyItem); 
      } 

      targetImage.Save(targetFile); 
     } 
    } 

    public static BitmapFrame ResizeHelper(BitmapFrame photo, int width, 
              int height, BitmapScalingMode scalingMode) 
    { 

     var group = new DrawingGroup(); 
     RenderOptions.SetBitmapScalingMode(
      group, scalingMode); 
     group.Children.Add(
      new ImageDrawing(photo, 
       new Rect(0, 0, width, height))); 
     var targetVisual = new DrawingVisual(); 
     var targetContext = targetVisual.RenderOpen(); 
     targetContext.DrawDrawing(group); 
     var target = new RenderTargetBitmap(
      width, height, 96, 96, PixelFormats.Default); 
     targetContext.Close(); 
     target.Render(targetVisual); 
     var targetFrame = BitmapFrame.Create(target); 
     return targetFrame; 
    } 

private static byte[] ToByteArray(BitmapFrame bfResize) 
{ 
    using (MemoryStream msStream = new MemoryStream()) 
    { 
     JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder(); 
     jpgEncoder.Frames.Add(bfResize); 
     jpgEncoder.Save(msStream); 
     return msStream.ToArray(); 
    } 
} 

private static BitmapFrame ReadBitmapFrame(Stream streamPhoto) 
{ 
    BitmapDecoder bdDecoder = 
     BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); 
    return bdDecoder.Frames[0]; 
} 

感謝, WTS

+0

帖子中引用的鏈接不再有效並導致可疑網站。 – 2017-10-23 15:17:56

+0

@AlexJorgenson - 刪除了現在7歲的鏈接 - 謝謝。 – 2017-10-23 19:05:22

回答

2

使用源圖像上的Image.PropertyItems屬性來獲取元數據項的列表。循環訪問列表,在目標圖像上調用Image.SetPropertyItem。您通常應該避免調整大小並重新壓縮jpeg圖像,從未壓縮的原始圖像處理最好能夠保持質量並避免失真。

+0

@Hans - 謝謝你的回答。僅供參考 - 調整大小隻是提高質量不成問題的應用程序效率的一種方式(儘管這將進行測試) - 我們也保留原始文件。 – 2010-08-20 15:57:18

+0

這是一個JPEG格式的圖像,調整大小使其更小,並保存回往往需要*更多*空間。 – 2010-08-20 16:04:18

+0

也許如果你使用targetImage.SetPropertyItem()而不是targetFile。期待我從這個問題診斷你的問題是不現實的。 – 2010-08-20 17:58:14

相關問題