2012-02-02 9 views
2

Delphi TCanvasを使用してJPEG画像を印刷する際に問題があります。 JPEGが黒の の正方形ではなく、30-50%の間で印刷されます。 を表示するために多くの設定を変更しようとしましたが、印刷に失敗する特定の条件がありましたが、何も書いていない時にはまだ動作していませんでした。黒いJPEG、または正しく印刷されるかどうかを確認します。Delphi - JPEGを読み込んで出力を黒い四角で印刷していますか?

ここでは、キャンバスにJPEGを印刷するためのコードを示します。

Screen.Cursor := crHourGlass; 
try 
    // initialize image 
    //>>imgImage := TImage.Create(Self); 
    imgImage := TImage.Create(Application); 

    // load image from file 
    imgImage.Picture.LoadFromFile(sFileNameAndPath); 

    // set width and height to that of loaded image 
    ////imgImage.Autosize := true; 
    ////Printer.Orientation := poPortrait; 
    // Header 
    Printer.Canvas.Font.Height := MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), 12, 72); 
    Printer.Canvas.Font.Name := 'Courier New'; 

    // Determine height and width of 1 printer-character 
    iDeltaW := Printer.Canvas.TextWidth('X'); 
    iDeltaH := Printer.Canvas.TextHeight('X'); 

    // ------------------------------ 
    // Method #1 - columns and lines 
    // ------------------------------ 
    // what column to printing from 
    iFromLeftMargin := iLeft * iDeltaW; 

    // what line to print from 
    iFromTopOfPage := iTop * iDeltaH; 

    // ------------------------------ 
    // Method #2 - pixels 
    // ------------------------------ 
    iPPW := Printer.PageWidth; 
    iPPH := Printer.PageHeight; 
    iIPW := imgImage.Picture.Width; 

    ePXW := iPPW/iInvImageWidth; 
    ePXH := iPPH/iInvImageHeight; 
    //~//iFromLeftMargin := Ceil(iLeft * pxW); 
    //~//iFromTopOfPage := Ceil(iTop * pxH); 
    iFromLeftMargin := Ceil(iLeft * ePXW); 
    iFromTopOfPage := Ceil(iTop * ePXH); 

    // Set printed bitmap width 
    iPrintedImageWidth := MulDiv(iPPW, iIPW, iInvImageWidth); 
    // Set printed bitmap height to maintain aspect ratio 
    iPrintedImageHeight := imgImage.Picture.Height * iPrintedImageWidth DIV 
    imgImage.Picture.Width; // maintain aspect ratio of bitmap 

    Bitmap := TBitmap.Create; 
    try 
    Bitmap.Width := imgImage.Picture.Width; 
    Bitmap.Height := imgImage.Picture.Height; 
    Bitmap.PixelFormat := pf24bit; 
    Bitmap.IgnorePalette := False; 
    // Convert JPEG (GIF, or whatever) to BMP 
    Bitmap.Canvas.Draw(0, 0, imgImage.Picture.Graphic); 

    // Print Image 
    PrintBitmap(Printer.Canvas, 
     Rect(iFromLeftMargin, iFromTopOfPage, 
      iFromLeftMargin + iPrintedImageWidth, 
      iFromTopOfPage + iPrintedImageHeight), 
      Bitmap); 
    finally 
    // free bitmap memory 
    Bitmap.Free; 
    end; 
    // free image memory 
    imgImage.Free; 
finally 
    Screen.Cursor := crDefault; 
end; 

誰にでもアイデアがあれば、非常に感謝しています。

よろしく、 ジェームズ

EDIT:以下PrintBitmapメソッドメソッドのコード。私はビットマップをディスクに保存してそれが生成されているときにそれを表示するようアドバイスしました。印刷された出力が黒い四角であっても黒い四角で保存されることはありません。私は、この問題がPrintBitmapコードにあることを示してほしい。

procedure PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap); 
var 
    BitmapHeader: pBitmapInfo; 
    BitmapImage: POINTER; 
    HeaderSize: DWORD; 
    ImageSize: DWORD; 
begin 
    GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize); 
    GetMem(BitmapHeader, HeaderSize); 
    GetMem(BitmapImage, ImageSize); 
    try 
    GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^); 
    StretchDIBits(Canvas.Handle, 
       DestRect.Left, DestRect.Top,  // Destination Origin 
       DestRect.Right - DestRect.Left, // Destination Width 
       DestRect.Bottom - DestRect.Top, // Destination Height 
       0, 0,       // Source Origin 
       Bitmap.Width, Bitmap.Height,  // Source Width & Height 
       BitmapImage, 
       TBitmapInfo(BitmapHeader^), 
       DIB_RGB_COLORS, 
       SRCCOPY); 
    finally 
    FreeMem(BitmapHeader); 
    FreeMem(BitmapImage); 
    end; 
end; {PrintBitmap} 

残念ながら、このコードは私の会社で働いていない人が書いたもので、既存の問題を修正しようとしています。

+2

コードを正しくフォーマットするために時間をかけてください。タブ文字は使用しないでください。インデントは4つのスペース文字で始まり、必要に応じてインデントにスペースを追加します。(あなたの質問を入力している場所のすぐ下を見て、あなたの投稿をリアルタイムでプレビューすることができるので、書式がどのようになっているのかが分かりやすくなります)。投稿時に書式を設定するだけでなく、これを行うだけでなく、読みやすいようにして、迅速に回答を得る良い機会を提供します。 :) –

+0

これはマルチスレッドアプリケーションですか?また、常に同じjpgファイルが失敗するのでしょうか? VCLはスレッドセーフではないので、私はこれまで同様の問題を抱えていたので、これを尋ねます。 – Steve

+0

あのケンのおかげで、不注意に申し訳ありません。こんにちはスティーブ - いいえ、そのシングルスレッドとは異なるJPEGファイルではなく、すべてではありません。 – jmc

答えて

3

あなたが投稿したスニペットでは分かりません。あなたは自己完結型の作業コード(compilableとrunnable)を投稿するべきです。
Begindoc/EndDocはありません。たとえば、ローカル変数宣言はありません。

さて、ローカル宣言を追加した後、iTopまたはiLeftなどの初期化されていない変数のためのコンパイラの警告の束があります。それらにランダムなゴミが残っていると、あなたが思うところを描かないことがあります。

あなたは常にあなたが常にpf24bit形式を保有していることを保証しているものとします。同じJPGがOKを印刷するかランダムに失敗するかを指定しないか、問題のあるJPGが異なる場合は、フォーマット変換の問題を排除することはできません。

無料のImage Debug Visualizerのいずれかをインストールし、PrintBitmapの前にブレークポイントを置き、印刷前にローカルBitmapが正しいかどうかを確認することをお勧めします。

次に、PrintBitmapの手順を見てみましょう...プリンタキャンバスに直接描画しようとしましたか?

更新:
PrintBitmapコードは、任意のリターンコードをチェックしないことを除いて、合法的なようだ:

if not GetDIB(...) then 
    raise [...]; 
if GDI_ERROR = StretchDIBits(...) then 
    RaiseLastOSError; 

問題は、プリンタ/ドライバから来るかもしれません。
別のプリンタまたは別のドライバで試しましたか?
また、プリンタが準備完了であることを確認してください。

+0

+1はあいまいな質問で、必然的に投機的です。たくさんの良い提案がここにあります。 –

+0

はい、ありがとうございました。私は印刷前にビットマップイメージを保存して表示することをアドバイスしましたが、それは常に正しいですし、ファイル内に黒い四角形として表示されません。問題のあいまいさで申し訳ありませんが、問題は多少ランダムに発生し、同じJPEGはいつでもOKまたは失敗します。残念なことに、このコードはあまり書かれておらず、アプリケーションの他の領域と密接に結びついているので、ここでは自己完結型のコードは難しいものです。 上記のPrintBitmapプロシージャを追加しました。 – jmc

+0

@jmc、私の更新を参照してください。その後、私は考えが尽きるのではないかと心配しています... –

関連する問題