2010-08-20 8 views
6

Tôi đang cố gắng thay đổi kích thước và lưu hình ảnh khá dễ dàng (ví dụ: xem ví dụ này ví dụ bên ngoài không còn hợp lệ).Thay đổi kích thước và lưu hình ảnh trong khi bảo quản siêu dữ liệu

Tuy nhiên, việc sử dụng mã này sẽ loại bỏ thông tin siêu dữ liệu khỏi hình ảnh. Tôi có thể không hoàn toàn có vẻ để tìm ra cách để bảo vệ siêu dữ liệu cho một hình ảnh jpeg.

** EDIT: Ví dụ Mã **

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]; 
} 

Cảm ơn, WTS

+0

Liên kết được tham chiếu trong bài đăng không còn hợp lệ và dẫn đến các trang web có vấn đề. –

+0

@AlexJorgenson - đã xóa liên kết 7 tuổi hiện tại - cảm ơn bạn. –

Trả lời

2

Sử dụng tài sản vào hình ảnh nguồn Image.PropertyItems để có được danh sách các mục siêu dữ liệu. Lặp lại danh sách, gọi Image.SetPropertyItem trên ảnh đích. Bạn thường nên tránh thay đổi kích thước và nén lại hình ảnh jpeg, làm việc từ bản gốc không nén là tốt nhất để duy trì chất lượng và tránh hiện vật.

+0

@Hans - cảm ơn bạn đã trả lời. FYI - Việc thay đổi kích thước chỉ là một cách để chúng tôi tăng hiệu quả trong một ứng dụng mà chất lượng không phải là một vấn đề (mặc dù điều này sẽ được kiểm tra) - chúng tôi cũng đang lưu giữ các tệp gốc. –

+0

Một hình ảnh jpeg được thay đổi kích thước để làm cho nó nhỏ hơn và lưu lại thường mất * nhiều hơn * không gian. –

+0

Có thể nếu bạn sử dụng targetImage.SetPropertyItem() thay vì targetFile. Mong đợi tôi để chẩn đoán vấn đề của bạn từ điều này là không thực tế. –