2014-11-04 1 views
1

다른 Tiff 그룹에서 생성 된 새로운 tiff의 해상도를 조정하려고했습니다. 해상도를 100x100 dpi로 떨어 뜨리고 싶습니다. 결합이있는 모든 것은 제대로 작동하지만 최종 Tiff의 해상도는 항상 합치고있는 파일의 해상도 (300x300 dpi 이미지 사용)입니다. PropertyItems를 가져 오거나 설정하기위한 몇 가지 제안 (Set DPI value to Tiff Image in C#)을 사용해 보았지만 실패했습니다. 아래의 결합 기술을 사용하여 최종 이미지의 해상도를 100x100dpi로 설정하는 올바른 방법은 무엇입니까?SetResolution은 tiff 이미지를 결합 할 때 아무 작업도하지 않습니다.

감사합니다.

public byte[] JoinTiffImages(
     List<byte[]> images) 
    { 
     var fPage = FrameDimension.Page; 

     var nearest = 
      System.Drawing 
        .Drawing2D 
        .InterpolationMode 
        .NearestNeighbor; 

     if (images.Count == 0) 
     { 
      throw new ImageConverterException(
       "Could not join an empty set of images."); 
     } 
     else if (images.Count == 1) 
     { 
      return images[0]; 
     } 
     else 
     { 
      using (var ms = new MemoryStream()) 
      { 
       using (var masterBitmap = 
        (Bitmap)DrawingImage.FromStream(
         new MemoryStream(images[0]))) 
       { 
        //get the codec for tiff files 
        var info = GetTifCodecInfo(); 
        var enc = Encoder.SaveFlag; 
        var ep = new EncoderParameters(2); 

        ep.Param[0] = new EncoderParameter(
         enc, 
         (long)EncoderValue.MultiFrame); 

        ep.Param[1] = new EncoderParameter(
         Encoder.Compression, 
         (long)TifCompression.ToEncoderValue()); 

        masterBitmap.SetResolution(100.0f, 100.0f); 
        masterBitmap.Save(ms, info, ep); 

        //save the intermediate frames 
        ep.Param[0] = new EncoderParameter(
         enc, 
         (long)EncoderValue.FrameDimensionPage); 

        for (int i = 1; i < images.Count; i++) 
        { 
         using (var nextImg = (Bitmap)DrawingImage.FromStream(
          new MemoryStream(images[i]))) 
         { 
          for (int x = 0; 
            x < nextImg.GetFrameCount(fPage); 
            x++) 
          { 
           nextImg.SetResolution(100.0f, 100.0f); 
           nextImg.SelectActiveFrame(fPage, x); 

           masterBitmap.SaveAdd(nextImg, ep); 
          } 
         } 
        } 

        ep.Param[0] = 
         new EncoderParameter(
          enc, 
          (long)EncoderValue.Flush); 

        //close out the file. 
        masterBitmap.SaveAdd(ep); 

        return ms.ToArray(); 
       } 
      } 
     } 
    } 
+0

이는/당신의 문제와 관련되지 않을 수 있지만, 당신은'img'라는 새로운 비트 맵을 만들 때 멀리 던지고 많은 일을하고, 그것에서 그래픽 객체를 가져, 페인트' nextImg'을 입력 한 다음 덤프하면됩니다. 'masterBitmap'에'img'을 추가하려고하는지 궁금합니다. 이와 함께 마스터에게'nextImg'를 추가하는 대신'img'의 해상도를 설정하고 마스터에 추가하려고 시도해 보았습니까? – pstrjds

+0

그려진 이미지와받는 이미지 모두에 대해 이미지를 그리는 데 __before__ 이상의 해상도를 설정해야합니다! 당신은 nextImg에 대해서는 올바르게하지만 masterBitmap에 대해서는 잘못합니다. – TaW

+0

당신이 * 예상 * 할 일이 꽤 명확하지 않습니다. 많이 기대하지 말아야 할 SetResolution()은 단순히 참조 번호를 설정합니다. 코드에 눈부신 버그가 있습니다. SaveAdd (nextImg, ep)는 반드시 * img *를 대신 사용해야합니다. 그리고 SetResolution()은 * img *에 대해 호출되지 않았습니다. 그리고 Rectangle을 사용하는 DrawImage() 오버로드를 사용해야합니다. –

답변

1

의견에 대한 도움으로 문제를 해결할 수있었습니다. 이 기능은 이미지가 크기를 변경하지 않고 해상도 변경을 처리합니다.

public static byte[] JoinTiffImages(
    List<byte[]> images, 
    float res) 
{ 
    var fPage = FrameDimension.Page; 

    var nearest = 
     System.Drawing 
       .Drawing2D 
       .InterpolationMode 
       .NearestNeighbor; 

    if (images.Count == 0) 
    { 
     throw new Exception(
      "Could not join an empty set of images."); 
    } 
    else if (images.Count == 1) 
    { 
     return images[0]; 
    } 
    else 
    { 
     var ms = new MemoryStream(); 

     //get the codec for tiff files 
     var info = GetTifCodecInfo(); 
     var ep = new EncoderParameters(2); 

     ep.Param[0] = new EncoderParameter(
      System.Drawing.Imaging.Encoder.SaveFlag, 
      (long)EncoderValue.MultiFrame); 

     ep.Param[1] = new EncoderParameter(
      System.Drawing.Imaging.Encoder.Compression, 
      (long)EncoderValue.CompressionLZW); 

     using (var masterImg = 
      (Bitmap)System.Drawing.Image.FromStream(
       new MemoryStream(images[0]))) 
     { 
      using (var resizedMaster = 
       new Bitmap(
        (int)(masterImg.Width * 
         (res/
          masterImg.HorizontalResolution)), 
        (int)(masterImg.Height * 
         (res/
          masterImg.VerticalResolution)))) 
      { 
       resizedMaster.SetResolution(
        res, 
        res); 

       using (var gr = Graphics.FromImage(resizedMaster)) 
       { 
        gr.InterpolationMode = nearest; 

        gr.DrawImage(
         masterImg, 
         new Rectangle(
          0, 
          0, 
          resizedMaster.Width, 
          resizedMaster.Height), 
         0, 
         0, 
         masterImg.Width, 
         masterImg.Height, 
         GraphicsUnit.Pixel); 
       } 

       resizedMaster.Save(ms, info, ep); 

       //save the intermediate frames 
       ep.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.SaveFlag, 
        (long)EncoderValue.FrameDimensionPage); 

       for (int i = 1; i < images.Count; i++) 
       { 
        using (var nextImg = 
         (Bitmap)System.Drawing.Image.FromStream(
         new MemoryStream(images[i]))) 
        { 
         for (int x = 0; 
          x < nextImg.GetFrameCount(fPage); 
          x++) 
         { 
          nextImg.SelectActiveFrame(fPage, x); 

          using (var resizedNext = 
           new Bitmap(
            (int)(nextImg.Width * 
             (res/
              nextImg.HorizontalResolution)), 
            (int)(nextImg.Height * 
             (res/
              nextImg.VerticalResolution)))) 
          { 
           resizedNext.SetResolution(
            res, 
            res); 

           using (var gr = 
            Graphics.FromImage(resizedNext)) 
           { 
            gr.InterpolationMode = nearest; 
            gr.DrawImage(
             nextImg, 
             new Rectangle(
              0, 
              0, 
              resizedNext.Width, 
              resizedNext.Height), 
             0, 
             0, 
             nextImg.Width, 
             nextImg.Height, 
             GraphicsUnit.Pixel); 
           } 

           resizedMaster.SaveAdd(resizedNext, ep); 
          } 
         } 
        } 
       } 

       ep.Param[0] = 
        new EncoderParameter(
         System.Drawing.Imaging.Encoder.SaveFlag, 
         (long)EncoderValue.Flush); 

       //close out the file. 
       resizedMaster.SaveAdd(ep); 
      } 

      return ms.ToArray(); 
     } 
    } 
} 

private static ImageCodecInfo GetTifCodecInfo() 
{ 
    foreach (var ice in ImageCodecInfo.GetImageEncoders()) 
    { 
     if (ice.MimeType == "image/tiff") 
     { 
      return ice; 
     } 
    } 

    return null; 
} 
+0

원본 이미지의 각 프레임을 조정할 수있는 기능이 추가되었습니다. 좋은 대답. –

1

다음은 이미지 목록에서 다중 페이지 tif 파일을 만드는 코드입니다. 입력 매개 변수에 따라 DPI를 마스터와 모든 파트에 설정합니다.

private void saveTiff_Click(List<Image> imgList, string saveName, int dpi) 
{ 
    //all kudos to : http://bobpowell.net/generating_multipage_tiffs.aspx 

    foreach (Image img in imgList) ((Bitmap)img).SetResolution(dpi, dpi); 

    System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.SaveFlag; 
    Bitmap master = new Bitmap(imgList[0]); 
    master.SetResolution(dpi, dpi); 
    ImageCodecInfo info = null; 

    // lets hope we have an TIF encoder 
    foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders()) 
     if (ice.MimeType == "image/tiff") info = ice; 

    // one parameter: MultiFrame 
    EncoderParameters ep = new EncoderParameters(1); 
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame); 
    master.Save(saveName, info, ep); 

    // one parameter: further frames 
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage); 
    for (int i = 1; i < imgList.Count; i++) master.SaveAdd(imgList[i], ep); 

    // one parameter: flush 
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush); 
    master.SaveAdd(ep); 
} 
관련 문제