2012-04-05 3 views
1

PDF에서 이미지를 추출하고 싶습니다. 지금 iTextSharp를 사용하고 있습니다. 일부 이미지는 올바르게 추출 할 수 있지만 대부분 이미지에 올바른 색이없고 왜곡되어 있습니다. 나는 다른있는 PixelFormats 몇 가지 실험을했다,하지만 난이 이미지-유형 구분하는 코드입니다 ... 내 문제에 대한iTextSharp를 사용하여 Exctract FlateDecode 이미지

을 솔루션을하지 않았다 :

if (filter == "/FlateDecode") 
{ 
    // ... 
    int w = int.Parse(width); 
    int h = int.Parse(height); 
    int bpp = tg.GetAsNumber(PdfName.BITSPERCOMPONENT).IntValue; 

    byte[] rawBytes = PdfReader.GetStreamBytesRaw((PRStream)tg); 
    byte[] decodedBytes = PdfReader.FlateDecode(rawBytes); 
    byte[] streamBytes = PdfReader.DecodePredictor(decodedBytes, tg.GetAsDict(PdfName.DECODEPARMS)); 

    PixelFormat[] pixFormats = new PixelFormat[23] { 
     PixelFormat.Format24bppRgb, 
     // ... all Pixel Formats 
    }; 
    for (int i = 0; i < pixFormats.Length; i++) 
    { 
     Program.ToPixelFormat(w, h, pixFormats[i], streamBytes, bpp, images)); 
    } 
} 

이것은에 코드입니다 이미지를 MemoryStream에 저장하십시오. 이미지를 폴더에 저장하는 것은 나중에 구현됩니다.

private static void ToPixelFormat(int width, int height, PixelFormat pixelformat, byte[] bytes, int bpp, IList<Image> images) 
{ 
    Bitmap bmp = new Bitmap(width, height, pixelformat); 
    BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, width, height), 
     ImageLockMode.WriteOnly, pixelformat); 
    Marshal.Copy(bytes, 0, bmd.Scan0, bytes.Length); 
    bmp.UnlockBits(bmd); 
    using (var ms = new MemoryStream()) 
    { 
     bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff); 
     bytes = ms.GetBuffer(); 
    } 
    images.Add(bmp); 
} 

도와주세요.

+0

5.1.3 이상의 새로운 기능을 사용하여이 응답을 확인하십시오. http://stackoverflow.com/a/8511314/231316 –

+0

그 해결책이 효과적 일 수 있습니다 (첫 번째 예제). 그러나 색상은 여전히 ​​역 또는 왜곡되어 있습니다. 답장을 보내 주셔서 감사합니다. –

답변

2

내 문제에 대한 해결책을 찾았습니다. 모든 페이지에서 모든 이미지를 추출하려면 다른 필터를 구현할 필요가 없습니다. iTextSharp에는 모든 이미지를 원래 이미지 유형으로 저장하는 이미지 렌더러가 있습니다.

은 그냥 여기서 발견 다음을 수행하십시오 당신은 HttpHandler를 ...

+0

사이트가 응답하지 않지만 Wayback Machine을 통해 스냅 샷을 사용할 수 있습니다. https://web.archive.org/web/20160714220626/http://kuujinbo.info/iTextSharp/CCITTFaxDecodeExtract.aspx –

1

PDF는 매우 다양한 이미지 형식을 지원합니다. 나는 당신이 여기에서 선택한이 접근 방법을 취할 것이라고 생각하지 않습니다. 스트림 자체의 바이트에서 이미지 형식을 결정해야합니다. 예를 들어, JPEG는 일반적으로 ASCII 바이트 JFIF로 시작합니다.

.NET (3.0+)에는 올바른 디코더를 선택하는 메서드가 있습니다. BitmapDecoder.Create. http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapdecoder.aspx

그래도 작동하지 않는 경우 일부 타사 이미징 라이브러리를 고려해보십시오. 나는 ImageMagick.NET과 LeadTools (비싸지 않은 방식)를 사용했다.

3

심지어 당신이 당신의 문제에 대한 해결책을 발견 구현 내가 제안은 위의 코드를 해결하기 위해 가정 해 봅시다 할 필요가 없습니다 http://kuujinbo.info/iTextSharp/CCITTFaxDecodeExtract.aspx .

왜곡 왜곡 문제는 행 데이터 경계의 불일치로 인해 발생한다고 생각합니다. PdfReader는 바이트 경계로 데이터를 반환합니다. 예를 들어, 20 픽셀 너비의 그레이 스케일 이미지의 경우 각 이미지 행에 20 바이트의 데이터가 제공됩니다. 비트 맵 클래스는 32 비트 경계에서 작동합니다. 20 픽셀 너비의 비트 맵을 만들 때 비트 맵 클래스는 스트라이드 (바이트 폭) = 32 바이트의 회색 음영 비트 맵을 생성합니다. 즉, ToPixelFormat() 에서처럼 Marshal.Copy() 메서드를 사용하여 PdfReader에서 검색 한 바이트를 새 비트 맵으로 간단히 복사 할 수 없습니다.

원본 바이트 배열의 첫 번째 픽셀은 21 번째 바이트이지만, 대상 비트 맵은 비트 맵의 ​​32 비트 경계 때문에 33 번째 바이트로 필요합니다. 이 문제를 해결하기 위해 각 데이터 행의 32 비트 경계를 고려한 크기의 바이트 배열을 만들어야했습니다.

PdfReader에서 검색 한 바이트에서 행별로 데이터를 복사하여 32 비트 행 경계를 고려한 새 바이트 배열로 복사합니다. 이제 Bitmap 클래스 경계와 일치하는 경계가있는 데이터 바이트를 갖게되어 Marshal.Copy()를 사용하여 새 Bitmap으로 복사 할 수있게되었습니다.

관련 문제