• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:メタファイルがうまく保存できない)

メタファイルが保存できない | Visual Studio2010 + VC + MFC

このQ&Aのポイント
  • MFCを使用してイメージを保存するプログラムを組んでいますが、Windows7ではファイル保存時に右側が欠けてしまいます。原因を教えてください。
  • MFCを使ったプログラムでメタファイルを作成し、図形を書き込んでファイルを保存しています。しかし、Windows7ではファイル保存時に右側が欠けてしまいます。原因が分かる方、教えてください。
  • Visual Studio2010 + VC + MFCを使用してイメージを保存するプログラムを開発しています。ただし、Windows7では右側が欠けてしまって思い通りの大きさでファイル保存できません。解決策を教えてください。

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8536/19406)
回答No.1

>pDCMeta->SetWindowExt(mmWidth, mmHeight); >pDCMeta->SetViewportExt(pxWidth, pxHeight); これらでエラーの発生を見ていないのが気になります。 スケーリング変更の際に、デバイスコンテキストに必要なだけの内部ビットマップを確保出来なかった場合、これらの関数はエラーを起こします。 XPで成功してWin7で失敗するなら、このような「内部ビットマップの確保の処理」のように、メモリの使用量の違いやシステム環境違いが動作に影響する処理の部分で何かが起きていると思われます。

ken2r
質問者

お礼

chie65535様 その後、調査し解決できましたので結果報告したいと思います。 現在、Viewのマップモードは、MM_ANISOTROPICを使い、 ピクセルとMMの変換には、GetDeviceCaps(LOGPIXELSX)を使っています。 詳しいことは分からないのですが、拡張メタファイルを作成するAPIは マップモードにMM_HIMETRICが使われているようです。 なので、CreateEnhMetaFileでサイズを指定する際のピクセルとMMの変換には 以下を使うようにしたら思いどおりのサイズの拡張メタファイルが作成でいました。 GetDeviceCaps(HORZSIZE); GetDeviceCaps(HORZRES); 有難うございました。

ken2r
質問者

補足

chie65535様、いつもご回答有難うございます。 SetMapMode()/SetWindowExt()/SetViewportExt()の戻り値を見たのですがエラーは 発生していませんでした。 ただ、気になる点があります。 WinXp(成功)と Win7(失敗)で作成した拡張メタファイルをWord2003に取り込んだ後、 イメージを選択し右クリックで「図の編集」を選択すると WinXP(成功)で作成したメタファイルは、イメージと同じ図形が描画されるのですが Win7(失敗)で作成したメタファイルはページに表示できないサイズに拡大され その中に描画した図形が表示されているようです。 WinXPとWin7でメタファイルの定義が変わったのでしょうか? または、設定が何か設定が足りないのでしょうか。 分かりづらい文章ですみません。 何か気づいた点などありましたら教えて下さい。 どうぞ宜しくお願い致します。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VC++でのアイコン背景透過について

    VC++2013 MFC環境です。 プログラムで○や×などの記号のアイコンを描画し、PNG,GIF,JPEGの形式でファイルに保存したいです。その時、アイコンの背景を透過したいのですがうまくいきません。 CDCクラスとCImageクラスを使用しアイコンの出力をしています。 背景透過について調べていくつか使えそうな関数があり試したのが、TransparentBltという関数で、デバイスコンテキストを二つ用意して、片方に記号を描画し、透過したい色を指定してもう片方にコピーすると指定した色が透過になる?と解釈しプログラム組みましたが結果は真っ黒の画像でした。 ここで完全に手が止まってしまい、質問させていただきます。 以下ソース CImage Image, image2; Image.Create( 50, 50, 24 ); image2.Create( 50, 50, 24 ); CDC* pDC = CDC::FromHandle( Image.GetDC( ) ); CDC* pdc2 = CDC::FromHandle( image2.GetDC( ) ); CRect rect( 0, 0, 50, 50 ); CPen BlackPen( PS_SOLID, 3, RGB( 0, 0, 0 ) ); CBrush WhitBrush( RGB( 255, 255, 255 ) ); CBrush BlackBrush( RGB( 0, 0, 0 ) ); pDC->FillRect( &rect, &WhitBrush ); pDC->SelectObject( &BlackPen ); pDC->SelectObject( &WhitBrush ); pDC->Ellipse( 5, 5, 45, 45 ); COLORREF col = Image.GetPixel( 0, 0 ); pdc2->TransparentBlt( 0, 0, 50, 50, pDC, 0, 0, 50, 50, col ); Image.SetTransparentColor( col ); image2.Save( L"c:\\icon\\maru.png" ); Image.ReleaseDC( ); image2.ReleaseDC( ); 他にも実装例があれば教えてください。 C++や画像生成に関しては経験がありません。

  • MFCで画像を表示させているのですが、透過表示する方法がわかりません。

    VC2005のMFCで画像を表示させているのですが、透過表示する方法がわかりません。 OnDraw(CDC* pDC) で、#include <atlimage.h>として、 CImage img; img.Load( "test.gif" ); CDC* pDCImg = CDC::FromHandle( img.GetDC() ); pDC->BitBlt( 60, 10, img.GetWidth(), img.GetHeight(), pDCImg, 0, 0, SRCCOPY ); img.ReleaseDC(); すればGIF画像が表示されましたが、このGIG画像は透過GIFですが そのまま表示されているので、背景が黒の場合透、明部分の白が見えて 四角い枠の画像となります。 GIF透過ファイルの場合、そのまま透過になる方法や、何か手段を用いて透過をさせたいです。

  • メモリーリークの原因

    お世話になっております。 VC2005を使用しております。 現在作成したいプログラムは、 (1)picture controlにて画像を編集する。(Pic1) (2)それをjpgファイルで保存する。 という事なのですが、下記プログラムにて、このルーチンを抜けた後に メモリーリークが発生してしまいます。saveの部分をコメントアウトすると発生しないため、ここが原因だと思いますが、どうして発生するかわかりません。 CImage SaveImage; RECT rect; CDC *pDC = m_Pic1.GetDC(); // ピクチャボックスのDC CDC *SaveImageDC;         //保存用のDC m_Pic1.GetClientRect(&rect); SaveImage.Create(rect.right,rect.bottom,24,0); SaveImageDC=CDC::FromHandle(SaveImage.GetDC()); SaveImageDC->BitBlt(0,0,rect.right,rect.bottom,pDC,0,0,SRCCOPY); SaveImage.Save("PP.jpg"); ReleaseDC(pDC); ReleaseDC(SaveImageDC); 何が悪いのか、どうすればよいか教えていただけないでしょうか? よろしくお願いします。

  • ビジオファイルをPDF形式で保存したい

    ビジオ(Microsoft Office Visio 2003)で作成した図ファイル(拡張子:.vsd)を入手しました。IE8で開けるのですが、これをPDF形式で保存したいと思います。 IEで開き、ファイル→印刷→AdobePDFで保存しますと、一応、PDFになるのですが、縦横比が狂って(縦長になって)しまい、また、下半分が欠けてしまいます。縦横比1:1の図として保存する方法が分かりましたら教えてください。

  • PictureControlのハンドルをCImageで取得

    お世話になっております。 VC2005を使用しております。 PictureControlで編集した画像を、CImageを使用してjpgファイルに保存することを行っております。 CDC *pDC = m_Pic.GetDC();でPictureControlのCDC取得 CImage SaveImage;で本体を宣言し、 CDC *SaveImageDC;でCDCを宣言します。 SaveImageDC->BitBlt(0,0,image.GetWidth(),image.GetHeight(),pdc,0,0,SRCCOPY);でコピー を行っておりますが、SaveImageとSaveImageDCを連動させる事ができません。 どのようにすればよいか教えてください。 よろしくお願いします。

  • 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); どうぞよろしくお願い致します。

  • CImage::ReleaseDC()のエラーで困っています。

    CImage::ReleaseDC()のエラーで困っています。 ウインドウ上に複数の画像を表示し、それぞれ配置や大きさを マウスのD&Dで変えられるようなアプリを作っています。 Visual Studio 2005 C++, MFC 画像はCImageクラスのm_ImageへLoadしてあります。 GetDCでハンドルを取得しているので、ReleaseDCにて開放を 行っていますが、そこで下のエラーになります。 [Second Chance Assertion Failed: File c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlimage.h, Line 1217] 何か解決のヒントになる事がありましたら教えてください。 void CImageButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { (前略) //ウィンドウDC互換Bitmap作成 CBitmap Bmp; Bmp.CreateCompatibleBitmap(pDC, nWidth, nHeight); //メモリDC作成 CDC MemDC; MemDC.CreateCompatibleDC(pDC); //メモリDCにBitmap選択 MemDC.SelectObject(&Bmp); //メモリDCにストレッチ描画 MemDC.SetStretchBltMode(HALFTONE); CDC* pImgDC = CDC::FromHandle(pBtnInfo->m_Image.GetDC()); HDC hImgDC = pImgDC->m_hDC; pBtnInfo->m_Image.StretchBlt(MemDC.m_hDC, 0, 0, nWidth, nHeight, SRCCOPY); pBtnInfo->m_Image.ReleaseDC(); (中略) //四角形を描画 CPen focusPen(PS_DOT, nPenWidth, RGB(nR, nG, nB)); CPen* OldPen = MemDC.SelectObject(&focusPen); MemDC.MoveTo(btnRect.left, btnRect.top); MemDC.LineTo(btnRect.left, btnRect.bottom); MemDC.LineTo(btnRect.right, btnRect.bottom); MemDC.LineTo(btnRect.right, btnRect.top); MemDC.LineTo(btnRect.left, btnRect.top); MemDC.SelectObject(OldPen); //メモリDCからウィンドウDCにビット転送 pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0 ,0, SRCCOPY); (後略)

  • ClistBoxでオーナードローがよくわかりません。

    CListBoxを派生させて オーナードローをしたのですが、(違うような気がするのですが) AddStringしても項目が追加できず 選択できるセルがありません。 ただ、描画がされているだけのようです。 また、AddStringの文字はどうやって表示するのでしょうか? 最終的には、以下のようなことがしたいと思っています。 左にアイコンがあり、ディレクトリごとに 段があるリストボックスです。 もうひとつ、 セルを透過させて背景にBitmapの表示。 こちらのほうで、オーナー描画が必要かなと思い 今に至ります。 ただ、オーナー描画のこととかよくわかっていません。 よろしくお願いします。 ------------------------------------------------ void CzListDlg::OnBnClickedButton1() { static int Cnt=6587; char Str[128]; itoa(Cnt,Str,10); List.AddString(Str); Cnt++; } BOOL CzListDlg::OnInitDialog() { *** List.Create(LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|WS_VISIBLE,CRect(0,0,120,200),this,5000); *** } ------------------------------------------------ void mList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC); pDC->TextOut(0,0,"Hello World");//←本当は、AddStringした文字がほしい pDC->TextOut(0,0,(char *)lpDrawItemStruct->itemData); } void mList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight=30; lpMeasureItemStruct->itemWidth=120; // TODO : ここにメッセージ ハンドラ コードを追加します。 }

  • リストボックスのオーナードローでInsertStringした文字列の取得

    ダイアログボックスの上にリストボックスを貼り付け、そのリストボックスを各行ごとに色を変て表示させることにトライしています。 なんとかかんとか調べて、 1.リストボックスのリソースで「Owner Draw=固定」に設定変更した。 2.そのリストボックスを持つクラスのウィンドウメッセージ    WM_DRAWITEM    WM_MEASUREITEM   にハンドラを追加した。 3.以下の様にハンドラを記述した。   void COwnerTestDlg::OnMeasureItem(int nIDCtl,       LPMEASUREITEMSTRUCT lpMeasureItemStruct)   {     lpMeasureItemStruct->itemHeight = 10/*1行の高さを設定*/;     CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);   }   void COwnerTestDlg::OnDrawItem(int nIDCtl,        LPDRAWITEMSTRUCT lpDrawItemStruct)   {     CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);     pDC->FillSolidRect(&lpDrawItemStruct->rcItem, RGB(0,0,0)/*背景の色*/);     pDC->SetBkColor(RGB(0,0,0)/*文字の後ろの色*/);     pDC->SetTextColor(RGB(255,255,255)/*文字の色*/);     pDC->TextOut(lpDrawItemStruct->rcItem.left,        lpDrawItemStruct->rcItem.top,        (char*)lpDrawItemStruct->itemData/*行に書かれた文字列*/);   } 4. CListBox* wp = (CListBox*)GetDlgItem(IDC_LIST1);     wp->InsertString(-1,"ADDED"); とやり、うまく表示されました。 ここまでは良かったのですが、 次に、4.のところを     char wbuf[256];     strcpy(wbuf,"ADDED");     wp->InsertString(-1,wbuf); とやったら文字化け(?)の様な、ちゃんと表示してくれなくなってしまいました。何がいけないのでしょうか?

  • オブジェクトの位置関係の設定条件を保存したい。

    Excel2007を使っています。 オブジェクトの位置関係の設定条件をデフォルト設定として保存する方法があればご教授お願いします。 任意の挿入した図形のサイズを【セルに合わせて移動するがサイズは変更ない】という作成条件で挿入していきたいのです。また、【縦横比を固定する】もチェックが必ず入るようにしたいです。 現状、図形を作成するごとにいちいちプロパティを開きチェックを入れないさないといけないため、し忘れなども発生し、確認するのが大変面倒です。 右クリックでの【既定の図形に設定】で保存されるかと試しましたが、反映されないようです。 上記の要望を叶える良い方法があればよろしくお願い致します。