画像の印刷について

このQ&Aのポイント
  • WIN98 VC++6.0 MFC環境での画像印刷の方法を教えてください。
  • TextOut()で書かれた文字は印刷プレビューで表示されるが、画像は表示されません。
  • CXxxViewのOnDraw関数にネイティブデータ用の描画コードを追加しています。
回答を見る
  • ベストアンサー

画像の印刷について

環境はWIN98 VC++6.0 MFCです。 初めて印刷に挑戦します。 TextOut()で書いた文字は印刷プレビューでちゃんと表示されましたが、以下のようにして取りこんだ画像を印刷プレビューで見ても何も表示されません。 どうしたら印刷できるようになりますか? void CXxxView::OnDraw(CDC* pDC) { CXxxDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: この場所にネイティブ データ用の描画コードを追加します。 CDC myDC; CBitmap myBMP; myBMP.LoadBitmap(IDB_BITMAP3); myDC.CreateCompatibleDC(pDC); CBitmap* oldBMP=myDC.SelectObject(&myBMP); pDC->BitBlt(10,10,60,100,&myDC,0,0,SRCCOPY); myDC.SelectObject(oldBMP); }

  • mk1234
  • お礼率94% (1832/1940)

質問者が選んだベストアンサー

  • ベストアンサー
  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.1

> pDC->BitBlt(10,10,60,100,&myDC,0,0,SRCCOPY); ここの(10,10)に描画している所で、デバイスによっては座標系が画面の座標系と違っているものがあります。 |用紙の描画範囲 | |×(10,-10) ┼――→ ↓×(10,10) 左下が原点(0,0)で用紙の中が(10,-10)とか。(10,10)は用紙の外側。 ヘルプのCDCクラスの「マッピング関数」「座標関数」の説明、用語を参考にして、webなどでも調べてみてはいかがでしょう? -- あと、同様の話で「半径10の円」でそこそこの大きさの円が描画される事を期待していると、用紙に印刷ゴミのような点が描画されていても気づかないような事があります。 この大きさのビットマップならば紙に出ていれば気が付くハズですが…。

mk1234
質問者

お礼

回答ありがとう御座います。 あれから分かったことは、 1.XPの場合は確かに非常に小さい絵になっていました。 これを大きくするにはどうすれば良いのですか? 2.WIN98の場合は、やはりまったくプレビューに出てきません。当然、印刷もされません。 これはどうすれば出てくるようになるのでしょうか? 3.また、言われているように座標系が変わっていたとして、通常のクライアント領域では見えるのに、プレビューでは領域外に飛び出して見えないなどと言うことが有るのでしょうか? お分かりの方、宜しくお願いいたします。

その他の回答 (3)

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.4

> XPでは印刷プレビューで表示されているし、印刷も出来るのに、WIN98では印刷プレビューで見れないし印刷も出来ないということが有るのでしょうか? デバイスコンテキスト(DC)を利用した印刷の場合、あくまでもプリンタ(ドライバ)に対して表示(印刷)の要求を行っていますので、OSが違う→デバイスドライバが違う以上、印刷結果が異なる事はありえます。 -- 適当に探した例ですと、 Windows 2000/XP対応 IPSiO Color 2000用 IPDL-Cドライバ Ver. 5.03 http://support.ricoh.com/pub_j/drivers/ricoh/ipc2000/ipdl-c/2000_xp/V503/html_j/dcc2503.htm Windows 95/98/Me対応 IPSiO Color 2000用 IPDL-Cドライバ Ver. 3.54 http://support.ricoh.com/pub_j/drivers/ricoh/ipc2000/ipdl-c/win95_me/V354/html_j/9cc2354.htm 後者のWin9x用のドライバの方にだけ以下のような記述がありました。 | 6)自作アプリ(VC++)からの出力で細い実線が印刷されない問題を修正しました。

mk1234
質問者

お礼

いろいろとありがとうございました。 どうも一筋縄でいかないようです。 以下でプレビューに表示することが出来ました。 //myBMP.LoadBitmap(_T("IDB_BITMAP1"));//IDB_BITMAP1);←ダメ //////// これでないとプレビューで見れない ///////// myBMP.Attach(::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)); あと、本格的なコードがあるサイトとして、 http://www.codeproject.com/printing/printlib.asp 画面をハードコピーし印刷するコード、 http://www.topposystem.co.jp/DL/Sample_Source/HardCopy(SourceCode).htm がありました。

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.3

> コードを書いた場所が悪いのでしょうか? 実は画面の処理って最近扱ってないんですが…。 コード自体は良いように見えます。 取りあえず、BitBltの返り値が正常終了(0以外)かどうかをチェックしてみてください。 正常終了ならば、描画自体は行われているハズなので、とてつもなく小さくなっているとか、用紙の外に描かれているとか、と分析できます。

mk1234
質問者

お礼

何度も回答ありがとう御座います。 自分でも当然調べますが、もう一度確認させてください。 XPでは印刷プレビューで表示されているし、印刷も出来るのに、WIN98では印刷プレビューで見れないし印刷も出来ないということが有るのでしょうか? 宜しくお願いいたします。

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.2

引き伸ばし/縮小の処理を行うには、通常なら CDC::StretchBlt を使用します。 プリンタ(ドライバ)のデバイスが対応している必要があります。 -- > やはりまったくプレビューに出てきません。 デバイスの座標系を考慮して描画処理を修正したが出てこない。と言う事でしょうか? // はみだした△を描画(てっぺんから時計回り、最後はちょっと右上にズレる) pDC->MoveTo( 0,-100) pDC->LineTo( 100, 100) pDC->LineTo(-100, 100) pDC->LineTo( 5,-110) のような図形が期待通りに描けるか、検証してみてください。 > 通常のクライアント領域では見えるのに、プレビューでは領域外に飛び出して見えないなどと言うことが有るのでしょうか? 座標系が変わる事によって、y範囲が正の部分が領域外にされてしまった場合、当然見えなくなります。 例えば、あるデバイスでは(12000,13000)に位置に点を打つと中心に表示、印刷されるような場合でも、画面だと領域外ですよね?

mk1234
質問者

お礼

回答ありがとう御座います。 >CDC::StretchBlt これは後から確認して見ます。 >図形が期待通りに描けるか、検証してみてください。 自分で描いた図形は問題ありません。 読み込んだビットマップのみプレビューで見えません。 コードを書いた場所が悪いのでしょうか? void CRrrView::OnDraw(CDC* pDC) { CRrrDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: この場所にネイティブ データ用の描画コードを追加します。 //■ここから追加 CDC myDC; CBitmap myBMP; myBMP.LoadBitmap(IDB_BITMAP1); myDC.CreateCompatibleDC(pDC); CBitmap* oldBMP=myDC.SelectObject(&myBMP); pDC->BitBlt(0,0,460,800,&myDC,0,0,SRCCOPY); myDC.SelectObject(oldBMP); //■ここまで追加 }

関連するQ&A

  • VisualC++6.0にてボタンにビットマップを表示させる方法

    VisualC++6.0のダイアログベースのアプリにおいて、 フォーム上に配置したボタン上にビットマップを表示 させたいと思ってます。OnPaint()の中で、以下のコード を書いたのですが、うまくいきません。  CWnd* myWnd = GetDlgItem(IDC_BUTTON1);  CDC* pDC = myWnd->GetDC();  CDC myDC;  CBitmap myBMP;  myBMP.LoadBitmap(IDB_BITMAP);  myDC.CreateCompatibleDC(pDC);  CBitmap* oldBMP = myDC.SelectObject(&myBMP);  pDC->BitBlt(0,0,100,100,&myDC,0,0,SRCCOPY);  myDC.SelectObject(oldBMP); ビットマップはちゃんと書かれてはいますが、その上にボタンが 描かれてしまうので、ビットマップが隠されてしまいます。 解決方法を教えてくださいますでしょうか。 よろしくお願いします。 % 絵をクリックするとアクションを起こすようにしたいので、 % ピクチャーボックスでも試してみました。これだとビット % マップはちゃんと表示されますが、BN_CLICKEDを書いて % ピクチャーボックスをクリックしてもOnPict()に処理が % 移りません。

  • ビューにビットマップファイルを描画する方法

    MFCのプログラムで(マルチウィンドウ)ビュー上に指定したビットマップファイルをオープンして描画したいと思ってます。 Bitmapリソースを指定して描画する方法はわかりましたが、ビットマップファイル名を指定して、そのファイルをオープンしてビュー上に描画する方法はどのようすればよいのでしょうか? 今は以下のようにOnDraw()内で以下のように実装しています。 -------------------------------------------------------- CBitmap kaitaGazou; kaitaGazou.LoadBitmap(IDB_BITMAP1); CDC MemDC; MemDC.CreateCompatibleDC(pDC); CBitmap *pTmpBitmap; pTmpBitmap = MemDC.GetCurrentBitmap(); MemDC.SelectObject(&kaitaGazou); pDC->BitBlt(0, 0, 100, 100, &MemDC, 10, 10, SRCCOPY); MemDC.SelectObject(pTmpBitmap); kaitaGazou.DeleteObject(); --------------------------------------------------------

  • CDCオブジェクトの作成について

    // あまり意味はないのですが、 //CDCのオブジェクトを宣言して、 //そこへ図形を描画して、 //クライエント領域にBitBltするときは、 //どうすればいいですか? //CreateCompatibleDCが関係していると思っています。 //ですが、上手く描画できません。 //教えてください、 //お願いします。 void CProject1View::OnDraw(CDC* pDC) { CProject1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; ////////////////////////////////////////////////////// CDC imageDC; CPen pen,*oldpen; pen.CreatePen(PS_SOLID,3,RGB(255,0,0)); imageDC.CreateCompatibleDC(pDC); for(int i=0;i<100;i++) { for(int j=0;j<100;j++) { imageDC.SetPixel(i,j,RGB(128,0,0)); } } oldpen=imageDC.SelectObject(&pen); imageDC.Rectangle(50,50,400,300); pDC->BitBlt(0,0,600,600,&imageDC,0,0,SRCCOPY); imageDC.SelectObject(oldpen); ////////////////////////////////////////////////////// }

  • LoadBitmapでCStringを使いたい

    VC++.NETでMFCアプリケーションを作っています。 CBitmap::LoadBitmapの定義では  BOOL LoadBitmap(LPCTSTR lpszResourceName); とあるのですが、リソースネームはCString型の変数では指定できないのでしょうか? ビットマップリソースがIDB_BMP1~IDB_BMP5まであり、状況により表示する画像を切り替える、ということをしたいのですが。   (略)  int n=1;  CString fname;  CBitmap bmp;  fname.Fromat("IDB_BMP%d",n);  bmp.LoadBitmap(fname);  pOldbmp = myDC.SelectObject(&bmp);  pDC->BitBlt(0, 300, 50, 77, &myDC, 0, 0, SRCCOPY);   (略) とすると画像が読み込まれません。 なお、LoadBitmapのfnameの部分を IDB_BMP1 と置き換えれば、画像は正常に表示できます。 MFC自体が初めてなので、分かりやすいご説明をいただけると嬉しいです。

  • ダイアログにビットマップを貼り付けた時にフリーズしてしまう

    お世話になります、fujicafeです。 現在、MFCにてダイアログベースのアプリケーションを作成中なのですが、ダイアログにビットマップを貼り付けてOnPaint()で表示するようにプログラムを作成したのですが、何度かダイアログの表示を繰り返すとOnPaintでのビットマップの読み込みが途中まででフリーズしてしまう現象が起きてしまいました。 プログラムは以下のように作成しています void C****Dlg::OnPaint() {  CDC* pDC = this->GetDC(); CDC myDC; CBitmap newbitmap; CBitmap* oldbitmap; CRect rc; GetClientRect(rc); newbitmap.LoadBitmap(IDB_BITMAP); myDC.CreateCompatibleDC( pDC ); oldbitmap=myDC.SelectObject( &newbitmap ); pDC->BitBlt( 0, 0, rc.Width(), rc.Height(), &myDC, 0, 0, SRCCOPY ); myDC.SelectObject(oldbitmap); } としています。 初めにこのダイアログを表示時は、ちゃんとビットマップが表示されるのですが、他のダイアログでこのダイアログを表示させた時にビットマップが上半分まで表示されて、動作がフリーズしてしまう現状です。 なにかよい打開策がありましたら、教えていただけたらと思っています。宜しくお願いいたします。

  • オブジェクトの削除について

    環境 WIN98 VC++6.0 MFC にて オブジェクトを使い終わってから削除している場合としていない場合が有るのですが、どうしてなのですか? 作ったオブジェクトはなんでもかんでも削除したほうが無難な気がしますが、本にのっているコードで削除してない場合も良く見かけます。 <削除していない>//著名な本のコード void Cxxx::OnDraw(CDC* pDC) {  CBitmap bmp;  bmp.LoadBitmap(nID);  略  //bmp.DeleteObject(); //■この記述が無い } <削除している>//ネット上でみかけたコード void CMainFrame::_SetBmp(CWnd* pBox,int nID,int  width,int height) // 単品 {  CDC* pDC=pBox->GetDC();  CDC memDC;  CBitmap bmp;  bmp.LoadBitmap(nID);  memDC.CreateCompatibleDC(pDC);  CBitmap* pOldBmp=memDC.SelectObject(&bmp);  pDC->BitBlt(0,0,width,height,&memDC,0,0,SRCCOPY);  memDC.SelectObject(pOldBmp);  bmp.DeleteObject();  memDC.DeleteDC(); }

  • mfcの画像表示で、bmp表示がよくわかりません

    mfcの画像表示で、bmp表示がよくわかりません。 特に、SelectObject()でBitmapを戻す等が特によくわかりません。 今までは、そういうもんだとしてきたのですが、放っておけない事態になりまして、 相談させて下さい。 (1)下記のbmpDC.SelectObject(oldbmp)等について、その仕組みを詳細に紹介しているHPを ご存じでしたらお教えください。 (2)下記プログラムの画像の扱いで、まずい部分を、おかしいなと思われた部分をお教えください。  動作は、問題なく動作しています。BITMAPを敷き詰めるプログラムです。 CArray<HBITMAP> hBitAry; (HBITMAPを配列にしているまずさは今回は除外して下さい。) … int topX=-100-5; int topY=0; int hLen=100; int wLen=100; int yoko=0; CDC *pDC=mPict.GetDC(); for(int i=0; i<hBitAry.GetCount(); i++) { CDC bmpDC; bmpDC.CreateCompatibleDC(pDC); CBitmap *pBitmap=CBitmap::FromHandle(hBitAry.GetAt(i)); BITMAP BMP; pBitmap->GetBitmap(&BMP); CBitmap *oldbmp=bmpDC.SelectObject(pBitmap); if(yoko<3) { topX+=100+5; yoko++; } else { topX=0; topY+=100+5; yoko=0; } pDC->SetStretchBltMode(COLORONCOLOR); pDC->StretchBlt(topX,topY,100,100,&bmpDC,0,0,BMP.bmWidth,BMP.bmHeight,SRCCOPY); bmpDC.SelectObject(oldbmp); ::DeleteObject(CBitmap::FromHandle(hBitAry.GetAt(i))); } ReleaseDC(pDC); どうぞよろしくお願い致します。

  • VC++にてボタン作成について(長文)

    VC++にて実行画面でボタンを表示させたいのですが、(表示するのはボタンだけではありません。)どのようにソースを書いたらいいのでしょう?Bitmapだったら、Viewクラスで ------------------------------------------------ CDC myDC; CBitmap newBitmap; CBitmap *pOldBitmap; newBitmap.LoadBitmap(画像の名前); myDC.CreateCompatibleDC(pDC); pOldBitmap=myDC.SelectObject(&newBitmap); pDC->BitBlt(10,10,320,240,&myDC,0,0,SRCCOPY); myDC.SelectObject(pOldBitmap); ------------------------------------------------ こんな感じかと思いますが、ボタンだったらどういった感じでソースを書いたらよいのでしょうか? また、こういったことを自分で調べたい場合には「ヘルプ」で何をキーワードにして検索したらよいのでしょう? VCを独学するのにどこか良いサイトはありますか?(できたら「ボタン」について詳しく説明してくれるサイトがいいです。) VCはほとんど素人なので簡単なことなのかも知れませんが、まったく分かりません。 ご存知の方、ご教授願います。

  • CFormViewでの印刷について

    環境はWIN98 VC++6.0 MFCです。 基本クラスをCViewにした場合は下記コードにて、印刷プレビューで画像が見れたのですが、基本クラスをCFormViewにしたら見れません。 どうすれば良いのでしょうか? void CxxxView::OnDraw(CDC* pDC) { if (pDC->IsPrinting()) { 下記URLのコード } else{ } 画像表示用コード http://www.codeguru.com/forum/showthread.php?threadid=234177

  • MFCプログラミング

    MFCのダブルバッファリングを用いて画面を切り替えるプログラムを作ったのですが 画面がちらついてしまいます、どう修正すればよいか教えてください // CgraphView 描画 void CgraphView::OnDraw(CDC* pDC) { CgraphDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: この場所にネイティブ データ用の描画コードを追加します。 CRect myRect; GetClientRect(myRect); if(background_color == 0) pDC->FillSolidRect(myRect, RGB(255, 255, 255)); else if(background_color == 1) pDC->FillSolidRect(myRect, RGB(153, 204, 255)); else pDC->FillSolidRect(myRect, RGB(255, 153, 204)); //ダブルバッファに関するコード CRect rc; GetClientRect(&rc); bkDC.CreateCompatibleDC(pDC); bkBMP.CreateCompatibleBitmap(pDC, rc.right, rc.bottom); CBitmap Bitmap, *pOldBitmap; pOldBitmap = bkDC.SelectObject(&bkBMP); //これから、すべての描画は、裏画面bkDCにおいて行う bkDC.FillSolidRect(rc, RGB(255, 255, 255)); int x, y, sx, sy; if(draw_state == 0) { bkDC.SetTextColor(RGB(0, 0, 0)); bkDC.TextOut(400, 500, _T("Start")); sx = 128;//表示するビットマップの横の大きさ sy = 128;//表示するビットマップの縦の大きさ y = 300;//表示するビットマップの左上の頂点のy座標 x = 50; draw_school(x, y, sx, sy); x = 200; draw_health(x, y, sx, sy); x = 350; draw_environment(x, y, sx, sy); } else if(draw_state == 1) { CRect myRect; GetClientRect(myRect); pDC->FillSolidRect(myRect, RGB(255, 255, 255)); } //裏画面bkDCにおいて、すべての描画を行った後 //裏画面を表画面に送る pDC->BitBlt(0, 0, rc.right, rc.bottom, &bkDC, 0, 0, SRCCOPY); bkDC.SelectObject(pOldBitmap); //裏画面を消去 bkBMP.DeleteObject(); bkDC.DeleteDC(); void CgraphView::OnInitialUpdate() { CView::OnInitialUpdate(); // TODO: ここに特定なコードを追加するか、もしくは基本クラスを呼び出してください。 bitmap[0].LoadBitmap(IDB_BITMAP1); bitmap[1].LoadBitmap(IDB_BITMAP2); bitmap[2].LoadBitmap(IDB_BITMAP3); bitmap[3].LoadBitmap(IDB_BITMAP4); bitmap[4].LoadBitmap(IDB_BITMAP5); bitmap[5].LoadBitmap(IDB_BITMAP6); Bmp_ID = 0; //タイマーをスタート SetTimer(ID_BITMAP, TIMER_MS_BITMAP, NULL); //画面再描画のタイマーをスタートする SetTimer(ID_REDRAW, TIMER_MS_FPS, NULL); Bmp_ID = 0; } void CgraphView::OnTimer(UINT_PTR nIDEvent) { // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 if(nIDEvent == ID_BITMAP) Bmp_ID = (Bmp_ID+1) % 2; if(nIDEvent == ID_REDRAW) InvalidateRect(NULL, FALSE); CView::OnTimer(nIDEvent); } void CgraphView::OnDestroy() { CView::OnDestroy(); // TODO: ここにメッセージ ハンドラ コードを追加します。 KillTimer(ID_BITMAP); KillTimer(ID_REDRAW); } void CgraphView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 mouse_x = point.x; mouse_y = point.y; if(draw_state == 0) { if(mouse_x > 400 && mouse_y > 500) { draw_state = 1; } } CView::OnLButtonDown(nFlags, point); } BOOL CgraphView::OnEraseBkgnd(CDC* pDC) { // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 return TRUE; //return CView::OnEraseBkgnd(pDC); }

専門家に質問してみよう