
どなたか経験のある方、わかる方居られましたら教えてください。
プリンタのデバイスコンテキストからメモリDCに描画してビットマップを作成したいと思っているのですが、プリンタDCからメモリDCへのBitBltがうまくいっていないのか、完成イメージが真っ黒になります。
hMemDC = CreateCompatibleDC(hPrinterDC);
hBitmap = CreateCompatibleBitmap(hPrinterDC,lnWidth,lnHeight);
Obj = (HBITMAP)SelectObject(hMemDC,hBitmap);
iRet = GetDeviceCaps(hMemDC,RASTERCAPS);
// iRet の戻り値は 28313(10進)でした。
// コピー
iRet = BitBlt(hMemDC,0,0,lnWidth,lnHeight,hPrinterDC,0,0,SRCCOPY);
// iRet の戻り値は 1 になってました。
本来は lnHeight の値が BitBlt の戻り値になるのかと思いますがうまくいきません。
hPrinterDC はもともと印刷用の関数で使用しているものなので、そこには問題が無いのではないかと自分では思っていますが、わかる方居られましたら教えていただけませんでしょうか?
No.1ベストアンサー
- 回答日時:
★Toyochan8 さんへ
・随分と苦戦していますね。
・過去に同じような質問を 3 つしていますが、解決していないようですね。
・私は『プリンタ・デバイス』を操作した経験はありませんが、気になった点を4つアドバイスします。
●1つ目
・まず『BitBlt』の戻り値ですが、MSDN のマニュアルでは BOOL 型になっていて正常終了すると TRUE を
返します。エラーが起きた場合は FALSE を返します。→『lnHeight』の値は戻り値に戻りません。
●2つ目
・GetDeviceCaps の行は、
『iRet = GetDeviceCaps(hMemDC,(RASTERCAPS|RC_BITBLT));』と
『iRet = GetDeviceCaps(hPrinterDC,(RASTERCAPS|RC_BITBLT));』の
2つを調べます。
戻り値を調べ『if (iRet & RC_BITBLT)』が真ならば BitBlt 関数を利用できます。
●3つ目
・『BitBlt』関数で上手くコピーできないならば、『StretchBlt』関数で長方形をコピーします。
つまり、
『BOOL bRet = StretchBlt(hMemDC,0,0,lnWidth,lnHeight,hPrinterDC,0,0,lnWidth,lnHeight,SRCCOPY);』
として転送します。このとき、StretchBlt 関数をサポートしているかどうかを
『iRet = GetDeviceCaps(hMemDC,(RASTERCAPS|RC_STRETCHBLT));』と
『iRet = GetDeviceCaps(hPrinterDC,(RASTERCAPS|RC_STRETCHBLT));』で
問い合わせます。戻り値を調べ『if (iRet & RC_STRETCHBLT)』が真ならば StretchBlt 関数を利用できます。
●4つ目
・フルカラーならビットマップのヘッダの『biBitCount = 16;』ではなく『biBitCount = 24;』とすべきです。
・さらに横方向のピクセル値は 4 バイト単位で揃えます。→横幅が 125 ピクセルならば、128 ピクセルとして
黒色データを 3 ピクセル余分に出力します。ここに注意して『.bmp』ファイルへ出力します。
・あと分かりやすく『biCompression = BI_RGB;』という定数にしましょう。
最後に:
・一度、メモリDC のビットマップ・データをウインドウへ描画して、コピーが正常かどうかを目で
確認してみて下さい。その後にファイルへビットマップを出力します。
・それとビットマップ・ファイルにパレットは使っていませんよね?もし使っていたら、パレットデータも正しく
出力しないと『真っ黒』になりますよ。→『RGBQUAD』構造体を参照
・あと VC++ Ver.15.1 を使っているようですが、『CreateFile』、『WriteFile』、『CloseHandle』の関数が
使えないのですか?
下に『_lwrite』関数を書き直した部分を載せます。→for文の方が分かりやすいですよ。
lCount = (long)LtpBitmapFH.bfSize - sizeof( BITMAPFILEHEADER );
for ( lBuffCnt = 0 ; lBuffCnt >= lCount ; lBuffCnt++ ){
Liret = _lwrite( hF, &szBuffer[lBuffCnt], 1 );
}
・以上。おわり。
Oh-Orangeさん、アドバイス有り難うございます。
『BitBlt』の戻り値の件は自分がGetDIBitsと勘違いしていました申し訳ありません。
GetDeviceCapsの件ですが教えて頂いたとおり書いてみましたがアクティブウインドウでも戻り値が0でした。自分の使い方まずかったんでしょうか・・。下のように使用しました。
iRet = GetDeviceCaps(hMemDC,(RASTERCAPS|RC_STRETCHBLT));
if (iRet & RC_STRETCHBLT) {
// TRUEの時の処理
ここは通りませんでした。
}
BMPのサイズの横幅は 560 なのでその点は大丈夫だと思います。
仕方なくプリンタのDCは中止してフォームを1つ作成してそこに描画したものをメモリDCにコピーさせることにしました、しかしこれも又うまくいかず・・。真っ黒にはならなかったのですが、フォーム上部の×ボタン、最大、最小化ボタンがあるエリアの左部分のアイコンのあたりが指定サイズのビットマップに拡大されて作成されてしまいました。取得データをフォームに描画しても同じ画像だったのでうまくメモリDCに受け取れていないと思います、有り難うございました。
No.2
- 回答日時:
とりあえず、3つのプリンタデバイスで実験してみました。
プリンタDCに画像を描画した直後に画像を取り出してみましたが、単色のビットマップイメージしか取り出せませんでした。
エプソンPM-890C:黒
PDF:黒
Dellのレーザプリンタ:白
プリンタによっては、画像が取り出せるかもしれませんが、通常はできないと思ったほうがよいと思われます。
ところで、どういう意図でプリンタDCからビットマップを取り出したいのでしょうか?
この回答への補足
tettsuさん、いつもアドバイス有難うございます。
わざわざ試していただき申しわけ有りません感謝します、単色だと取り出せる事もあるんですね。
その場合ヘッダ情報のBitCount を1にすればいいだけなのでしょうか?
通常出来ないと思ったほうが良いということなので、新規フォームを作成してそこに描画したイメージをビットマップにすることにしました。
残された時間も少なくなってきて、少し行き詰まってますがもうちょっと考えてみたいと思います。
プリンタDCから取り出したいと思ったのは印刷用のDLLがあったのでそれの終了時のDCから取り出せば早いのかなと思ったからです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Illustrator(イラストレーター) アイビスペイント、原稿作成について 1 2023/07/14 03:01
- ノートパソコン 自作にするか、メーカーか、オススメのノートPCをおしえてください。 5 2022/11/29 17:42
- その他(ソフトウェア) F-BASICで計算中の実行が中途で勝手に止まり、大変困っています。 2 2023/03/02 16:15
- PDF AutoCAD図面をPDF fileに変換した際、画像情報やブロック名はわかるのでしょうか。 1 2022/06/03 09:42
- PDF 2つのPDFを重ねる方法はありますか? 4 2023/01/30 14:04
- プリンタ・スキャナー ブラザ-製プリンタ-DCP-J582N不具合改善アドバイス依頼 2 2022/10/17 15:40
- デスクトップパソコン キャプチャーボードDRECAP DC-HC4のドライバー 1 2022/05/30 15:40
- デスクトップパソコン pcが1日に3-4回ほどフリーズするようになりました。 ゲームのプレイや特定のサイト(Twitchな 1 2023/06/16 04:25
- Excel(エクセル) Excelで全クラスのランキング表を作成したい 4 2022/05/24 15:28
- Java Java モンスターブリーダー 1 2023/02/05 09:44
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コマンド(例えばls)の出力結果...
-
ファイル出力の場所を指定
-
ファイルの文字コードをUTF-8に...
-
Visual Basic 6.0で 1行 読...
-
C++/CLIにて、System.String^型...
-
VB.NETでExcelファイルを出力す...
-
C++ fprintf_sの使い方がわからん
-
シェルコマンドの 2>&1 とはど...
-
FORTRANの出力データの左寄せが...
-
【ExcelVBA】UTF-8(BOM無)でC...
-
Wordマクロで指定したフォルダ...
-
Accessでのレポート印刷待機方法
-
CBool関数について VB6とVB.net...
-
VBA でメモ帳へ保存する際の保...
-
エクセルVBA→シート名でCSV出力...
-
C言語でプログラムを作成しなさ...
-
BitBltについて。
-
特定の列・行をテキストファイ...
-
CSV形式に変換
-
PDFファイルを指定の名前でプロ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【ExcelVBA】UTF-8(BOM無)でC...
-
テキストファイルに改行コード...
-
コマンド(例えばls)の出力結果...
-
VC++でUTF-8のファイルを出力し...
-
シェルコマンドの 2>&1 とはど...
-
Acccess レポートをグループ別...
-
ファイル形式またはファイル拡...
-
pcap形式データをテキストへ抽出
-
ファイル出力の場所を指定
-
AccessVBA複数レポート条件毎に...
-
外国語とCSVについて
-
VBA でメモ帳へ保存する際の保...
-
サウンド出力のデバイスを選択...
-
C++ fprintf_sの使い方がわからん
-
アプリを実行すると、作成者を...
-
ファイルの文字コードをUTF-8に...
-
1行ずつではなくまとめてファイ...
-
Wordマクロで指定したフォルダ...
-
SendKeys "^V", True(貼り付け...
-
CSVファイルを任意の場所に出力...
おすすめ情報