2013-01-15 4 views
0

티파니 파일의 마지막 페이지에서 몇 가지 작업을해야합니다. 그래서 아래의 예제 코드를 작성했는데 작동하지만 천천히 작동합니다. 코드는 결국 조금씩 실행될 것이고 속도를 올려야합니다.전체 파일을 쓰지 않고 다중 페이지 티파니를 저장합니다.

나는 멀티 스레드 방식을 사용하여 연주 해왔다.하지만 결국에는 모든 데이터가 동일한 파일에 쓰여 져야하고 시간이 많이 걸리는 부분으로 보인다.

전 마지막 페이지에서만 작업하는 방법이나 아직 고려하지 않은 것을 보여줄 수있는 답변이 필요합니다.

private void rotateLastPage() { 
    string inputfile = "C:\\input.tif"; 
    string tmpfile = inputfile + ".tmp"; 

    Bitmap bmap = (Bitmap)Image.FromFile(inputfile); 
    int max = bmap.GetFrameCount(FrameDimension.Page); 

    Image[] images = new Image[max]; 
    int i; 
    for (i = 0; i < max; i++) 
    { 
      bmap.SelectActiveFrame(FrameDimension.Page, i); 
      images[i] = (Image)bmap.Clone(); 
    } 
    bmap.Dispose(); 

    Bitmap pages = null; 
    i = 0; 
    foreach(Image image in images) 
    { 
     try 
     { 
      if (i == max - 1) 
      { 
       image.RotateFlip(RotateFlipType.Rotate90FlipNone); 
      } 
      EncoderParameters encoderParameters = new EncoderParameters(2); 
      encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame); 

      Int16 c = BitConverter.ToInt16(image.PropertyItems[Array.IndexOf(image.PropertyIdList, 0x103)].Value, 0); 

      if (c != 4 && c != 5) 
      { 
       throw new ArgumentException("Only CCIT4 and LZW compressed images are allowed."); 
      } 
      else if (c == 4) 
      { 
       encoderParameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4); 
      } 
      else if (c == 5) 
      { 
       encoderParameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW); 
      } 

      if (i == 0) 
      { 
       pages = (Bitmap)image; 
       ImageCodecInfo encoder = getTiffEncoder(); 
       pages.Save(tmpfile, encoder, encoderParameters); 
      } 
      else 
      { 
       encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage); 
       pages.SaveAdd(image, encoderParameters); 
      } 

      if (i == max - 1) 
      { 
       encoderParameters = new EncoderParameters(1); 
       encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush); 
       pages.SaveAdd(encoderParameters); 
      } 
      i++; 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(String.Format("Unable to rotate page {0} in file {1} due to {2}", (i + 1).ToString(), inputfile, e.Message)); 
      break; 
     } 
    } 

    foreach (Image image in images) { 
     image.Dispose(); 
    } 
    pages.Dispose(); 

    // eventually overwrite input file with tmp file 
} 

private static ImageCodecInfo getTiffEncoder() 
{ 
    ImageCodecInfo encoder = null; 
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); 
    for (int i = 0; i < encoders.Length; i++) 
    { 
     if (encoders[i].MimeType == "image/tiff") 
     { 
      encoder = encoders[i]; 
     } 
    } 
    if (encoder == null) 
    { 
     throw new NotSupportedException("Unable to find a tiff encoder."); 
    } 
    return encoder; 
} 
+0


편집 : (EDIT 작동하지 않을 것) 제목을 수정했습니다. [ "제목에"태그에 "태그가 포함되어 있어야합니까?"] (http://meta.stackexchange.com/questions/19190/), 컨센서스는 "아니오, 그렇지 않아야합니다."를 참조하십시오. – Default

답변

1

foreach 루프와 for 루프를 하나씩 사용하고 있습니다. 목록을 사용하는 경우 마지막 페이지는 images.Last()에 의해 액세스되고 첫 번째 페이지는 images.First()에 의해 액세스되어 해당 이미지 객체를 반환합니다.

또한 지금 당장 당신은 모든 단일 이미지를 저장하는 것처럼 보입니다. 나는 얼마나 많은 페이지를 가지고 있는지 모르지만, 그것들이 무리라면, 오래 걸릴 수도 있습니다. 당신은 그것들을 모두 처리하려고 시도 했습니까? 그리고 결국에는 한번에 모두 저장 했습니까? 하드 디스크에 액세스하려면 시간이 많이 걸리기 때문입니다. 그 문제는 텍스트 파일의 특정 줄을 처리하고 한 번 새로운 줄에 저장할 때 ..... "전체 파일을 쓰지 않고"라는 제한을 의미하지 않는다면.

희망 하시겠습니까?

1

임시 파일로 작업하는 대신 원래 파일에서 작업하고 마지막 페이지에 회전 만 저장할 수 있습니다. 복제 첫 번째 프레임 만, 다른 모든 프레임을 추가하고이 같은 마지막 ..

뭔가 회전 : 내가 가지고있는

public void rotateLastPage() 
    { 
     string inputfile = @"u:\\input.tiff"; 

     Bitmap bmap = (Bitmap)Image.FromFile(inputfile); 
     int max = bmap.GetFrameCount(FrameDimension.Page); 

     try 
     { 
      EncoderParameters encoderParameters = GetEncoderParameters(bmap, EncoderValue.MultiFrame); 
      ImageCodecInfo encoder = GetTiffEncoder(); 
      var firstPage = (Image)bmap.Clone(); 
      firstPage.Save(inputfile+".tmp", encoder, encoderParameters); 
      for (int i = 1; i < max - 1; i++) 
      { 
       bmap.SelectActiveFrame(FrameDimension.Page, i); 
       encoderParameters = GetEncoderParameters(bmap, EncoderValue.FrameDimensionPage); 
       firstPage.SaveAdd(bmap, encoderParameters); 
      } 
      bmap.SelectActiveFrame(FrameDimension.Page, max - 1); 
      bmap.RotateFlip(RotateFlipType.Rotate90FlipNone); 
      encoderParameters = GetEncoderParameters(bmap, EncoderValue.FrameDimensionPage); 
      firstPage.SaveAdd(bmap, encoderParameters); 
      firstPage.SaveAdd(GetEncoderParameters(EncoderValue.Flush)); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(String.Format("Unable to rotate page {0} in file {1} due to {2}", max.ToString(), inputfile, e.Message)); 
     } 
     bmap.Dispose(); 
    } 

    private static EncoderParameters GetEncoderParameters(Image image, EncoderValue encoderValue) 
    { 
     EncoderParameters encoderParameters = new EncoderParameters(2); 
     encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)encoderValue); 
     encoderParameters.Param[1] = GetCompressionEncoder(image); 
     return encoderParameters; 
    } 
    private static EncoderParameters GetEncoderParameters(EncoderValue encoderValue) 
    { 
     EncoderParameters encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)encoderValue);    
     return encoderParameters; 
    } 

    private static EncoderParameter GetCompressionEncoder(Image image) 
    { 
     Int16 c = BitConverter.ToInt16(image.PropertyItems[Array.IndexOf(image.PropertyIdList, 0x103)].Value, 0); 

     if (c == 4) 
     { 
      return new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4); 
     } 
     else if (c == 5) 
     { 
      return new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW); 
     } 
     throw new ArgumentException("Only CCIT4 and LZW compressed images are allowed."); 
    } 

    private static ImageCodecInfo GetTiffEncoder() 
    { 
     ImageCodecInfo encoder = null; 
     ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); 
     for (int i = 0; i < encoders.Length; i++) 
     { 
      if (encoders[i].MimeType == "image/tiff") 
      { 
       encoder = encoders[i]; 
      } 
     } 
     if (encoder == null) 
     { 
      throw new NotSupportedException("Unable to find a tiff encoder."); 
     } 
     return encoder; 
    } 
+0

게시 된 코드와 일치하도록 코드를 다시 작성하면 파일의 마지막 페이지가 회전되지만 파일의 페이지도 마지막 페이지로 축소됩니다. 게시 된 코드를 실행하고 다른 결과를 얻었습니까? – CodeReaper

+0

@ CodeReaper, 네, 첫 번째 프레임을 유지하는 것 같습니다 ... – knaki02

+0

게시 된 코드를 깨끗한 새 프로젝트로 가져 와서 실행했습니다. Console.WriteLine (...)을 MessageBox.Show (...)로 바꾸면 회전 된 이미지가 저장되지 않도록하는 예외가 발생합니다. 예외가 발생하지 않으면 남아있는 마지막 페이지 만 있습니다. – CodeReaper