![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?c9bd177)
VC++のMFC、ダイアログベースで画像処理のソフトを開発している者です。
ピクチャーコントロールに画像を表示させて、その画像を保存したいと思っています。
保存用のダイアログを開き、名前を付けて保存したいのですがうまくいきません。
下が今作っているプログラムです。
void Cstart2Dlg::OnBnClickedButton10()
{
CFileDialog myDLG(FALSE,"BMP","*.BMP",
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"画像(*.BMP)|*.BMP||");
if(myDLG.DoModal() == IDOK){
CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate
|CFile::modeWrite|CFile::typeBinary);
UpdateData(TRUE);
fout.WriteString(m_pict8);
fout.WriteString("\xla");
filename = myDLG.GetPathName();
SetWindowText("start2"+filename);
}
ピクチャーコントロールの変数をm_pict8にしています。テキストファイルを保存するプログラムを参考にして作っているので間違っているのだと思います。
画像の保存方法が分かる方がいらっしゃいましたらよろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
こんにちは。
ビットマップファイルの場合、セーブする為の手順は
BITMAPFILEHEADER → BITMAPINFOHEADER → RGBQUADテーブル → イメージデータ
と言った具合です。RGBQUADテーブル(パレットテーブル)は、何ビットイメージでセーブするかによって、テーブル長が変化します。
さて、何ビットイメージでセーブをお望みでしょうか。
No.2
- 回答日時:
こんばんは。
補足頂きました。24bitフォーマットならば、特に難しい事は有りません。
イメージ全体のサイズが4の倍数に満たない場合、ダミーバイトを付け加えてサイズの調整しないといけません。此れを怠ると、別のソフトで開いた時にほぼ間違いなく可笑しくなります。
また、パレットイメージを所有していない為、RGBQUADテーブル(パレットテーブル)の作成も必要有りません。
改善の余地もあるとは思いますが、以下参考程度に。
//1スキャンライン辺りの4バイト調整をした数字を求める
static LONG CalcScanLineByte(const LONG w, const WORD bpp)
{
return (((bpp * w) + 31) / 32) * 4;
}
+---------------------------------------------------------------------------------------
セーブする時
//ファイルを開く
CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate | CFile::modeWrite|CFile::typeBinary);
//ピクチャボックスからビットマップを取り出す
HBITMAP hBitmap = m_pict8.GetBitmap();
//無いので処理できない
if(hBitmap == NULL)return;
//ビットマップの情報を取る
BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
//4バイト調整したスキャンラインのサイズ
const int iScanLineByte = ::CalcScanLineByte(bitmap.bmWidth, bitmap.bmBitsPixel);
//ファイルヘッダとビットマップヘッダ
BITMAPFILEHEADER bmfh = {sizeof(bmfh)};
BITMAPINFOHEADER bmif = {sizeof(bmif)};
//ビットマップである事を示す名称
bmfh.bfType = ('M' << 8) | 'B';
//イメージデータへのオフセットはファイルヘッダ+ビットマップヘッダ
bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmif);
//見ての通り
bmif.biBitCount = 24;
//24ビットの時はBI_RGBで固定
bmif.biCompression = BI_RGB;
//常に1で固定
bmif.biPlanes = 1;
//見ての通り
bmif.biWidth = bitmap.bmWidth;
bmif.biHeight= bitmap.bmHeight;
//4バイト調整も含めた正確な合計バイトサイズが必要
bmif.biSizeImage = iScanLineByte * bmif.biHeight;
//ファイルヘッダ→ビットマップヘッダの順番に書き出す
fout.Write(&bmfh, sizeof(bmfh));
fout.Write(&bmif, sizeof(bmif));
//イメージデータをセーブする
HDC hMemDC = ::CreateCompatibleDC(NULL);
::SelectObject(hMemDC, hBitmap);
//yを縦幅-1から回転させないと上下逆転してしまう
for(int y = bmif.biHeight - 1; y >= 0; --y)
{
//3バイトずつステップする
for(int x = 0; x < iScanLineByte; x += 3)
{
const COLORREF cref = ::GetPixel(hMemDC, x / 3, y);
//色素の位置関係をBGRにしないと赤と青の関係が逆転してしまう
const BYTE arrBy[3] = {GetBValue(cref), GetGValue(cref), GetRValue(cref)};
//1ピクセル分(3バイト)書き出す
fout.Write(arrBy, sizeof(arrBy));
}
}
::DeleteDC(hMemDC);
この回答への補足
2度もご回答本当にありがとうございます。もう少しでうまくいきそうなのですが、
CFileDialog myDLG(FALSE,"BMP","*.BMP",
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"画像(*.BMP)|*.BMP||");
の部分に、「2 番目の引数を 'const char [4]' から 'LPCTSTR' に変換できません。」というエラーが出てしまいす。どうしたら解決できるのか、ご指導お願いいたします。
先ほどの問題はなんとか解決することができました。
またまたお手数なのですが、32ビットの保存方法も教えていただけないでしょうか。
よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- Excel(エクセル) エクセルのマクロについて教えてください。 2 2023/02/21 13:29
- Excel(エクセル) EXCELマクロでandroidタブレットから取りんだJPEGファイルをうまくセルに貼り付けられない 2 2022/07/31 15:03
- ノートパソコン PCのshift+右クリックについて 2 2022/08/22 08:52
- その他(ソフトウェア) コマンドプロンプトについて教えてください。 状況: 画像編集ソフト上でネットから保存した画像を使うの 3 2022/05/26 11:14
- 教えて!goo 「教えて!goo」や「Yahoo知恵袋」に投稿する際の画像についてお聞きします。 2 2023/05/23 12:53
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- その他(プログラミング・Web制作) ホームページビルダー16で画像を保存したら画像がトップページ上に沢山出てきてしまいます 1 2022/12/06 14:50
- Visual Basic(VBA) Excelのマクロコードについて教えてください 1 2022/03/27 12:02
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
ビットマップに描画をしてピクチャーコントロールに貼り付けるためには?
C言語・C++・C#
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
-
4
MFC - ダイアログボックスのPictureControlへの画像表示
C言語・C++・C#
-
5
MFCでOnPaintのタイミング
C言語・C++・C#
-
6
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
7
VC++プログラムをつかったBMP画像の拡大縮小について
C言語・C++・C#
-
8
デバイスコンテキストに書いた絵をBMPファイルに落としたいです。
C言語・C++・C#
-
9
リソースエディタでスタティックテキストの文字サイズの変更
C言語・C++・C#
-
10
起動後直に実行するコードはどこに?
C言語・C++・C#
-
11
bitmap画像の保存がうまくいきません。
C言語・C++・C#
-
12
MFCで画像を表示させているのですが、透過表示する方法がわかりません。
C言語・C++・C#
-
13
CImageクラスの使用について
C言語・C++・C#
-
14
StretchBlt関数について
C言語・C++・C#
-
15
C++初心者です。 debug assertion errorについて
C言語・C++・C#
-
16
RGBのバイナリデータをCImageにコピー
C言語・C++・C#
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッファとは何ですか
-
EXCEL VBAでテキストファイルの...
-
ページ読み込み時に自動的にsub...
-
EOF
-
ゲームのパラメータの読み込み...
-
Microsoft VBAで2GBを超えるフ...
-
VBでCSVファイルを読み込む方法...
-
バイナリエディタのつかいかた
-
バイナリ形式など、ファイルサ...
-
エンディアンと2の補数表現
-
地熱発電などでいう「バイナリ...
-
ファイルをセーブする時のfopen...
-
ファイルを音声で持ち帰りたい
-
デバイスファイルに書き込むこと
-
テキストデータをSQLServerに取...
-
Javaでのエンディアン変換
-
VBAでDOS-V形式のデータをエク...
-
テキストデータをバイナリデー...
-
エラー:ストリームの終わりを...
-
VBAを使って、一部バイナリデー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッファとは何ですか
-
Microsoft VBAで2GBを超えるフ...
-
EXCEL VBAでテキストファイルの...
-
バイナリエディタのつかいかた
-
ページ読み込み時に自動的にsub...
-
VBA バイナリ―から文字列にす...
-
エクセルVBA 2千万行のCSVファ...
-
エラー:ストリームの終わりを...
-
EOF
-
【python】Excelファイルを読み...
-
EXCEL VBAで、バイナリデータの...
-
入力ファイルをバイナリにする利点
-
DXFファイル用クラスライブラリ...
-
バイナリーデータの一部データ...
-
C言語とシリアル通信の送受信...
-
C言語の質問です。バイナリ形...
-
Javaでのエンディアン変換
-
24ビットのWaveデータの中身に...
-
bitmap画像の保存がうまくいき...
-
PHPのfgetcsvの処理容量について
おすすめ情報