2012-04-05 34 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)); 
    } 
} 

これは、コードにありますImageを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にはイメージレンダラーがあり、すべてのイメージを元のイメージタイプで保存します。

ちょうど次はこちらをご覧ください:http://kuujinbo.info/iTextSharp/CCITTFaxDecodeExtract.aspx をあなたがの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

も、あなたは私が上記のコードを修正するための提案を言わせて、あなたの問題の解決策を見つけました。

私は歪みの問題が行データ境界の不一致のために発生したと考えています。 PdfReaderはバイト境界でデータを返します。たとえば、20ピクセルのグレースケール画像の場合、各画像行につき20バイトのデータが得られます。ビットマップクラスは32ビット境界で動作します。幅20ピクセルのビットマップを作成する場合、ビットマップクラスはストライド(バイト幅)= 32バイトのグレースケールビットマップを生成します。つまり、ToPixelFormat()にあるように、Marshal.Copy()メソッドを使用してPdfReaderから取得したバイトを新しいビットマップに単純にコピーすることはできません。

ソースバイト配列の最初のピクセルは21バイト目に位置しますが、宛先ビットマップはビットマップの32ビット境界のため33バイト目になります。この問題を解決するために、各データ行の32ビット境界を考慮したサイズのバイト配列を作成しなければなりませんでした。

PdfReaderから取得したバイトから行ごとにデータをコピーし、32ビット行境界を考慮した新しいバイト配列にコピーします。これで、Bitmapクラスの境界に一致する境界を持つデータのバイトが得られました。そのため、Marshal.Copy()を使用して新しいビットマップにコピーできます。

関連する問題