前回質問させていただいたのですが
質問を打ち切ってしまい そのあと試したのですが
うまくいきません。
Window画面に表示はしたくないのです。
クリップボードの画像をファイルに保存したいのですが
以下のソースでどこがおかしいでしょうか
case IDM_SAVE:
hdc = BeginPaint(hWnd, &ps);
if (IsClipboardFormatAvailable(CF_BITMAP))
{
OpenClipboard(hWnd);
hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
hdc_mem = CreateCompatibleDC(hdc);
SelectObject(hdc_mem, hBitmap);
GetObject(hBitmap,(int)sizeof(bmp_info),&bmp_info);
width=bmp_info.bmWidth;
height=bmp_info.bmHeight;
MessageBox(NULL,"Debug 0","Debug0",MB_OK);
fopen_s(&fpt,"ClipBoard.bmp","wb");
BITMAPINFOHEADER bmih;
BITMAPFILEHEADER bmfh;
//RGBQUAD rgbquad;
DWORD filesize,bmfhsize,bmihsize;
bmfhsize=sizeof(bmfh);
bmihsize=sizeof(bmih);
//rgbquadsize=sizeof(rgbquad);
filesize=bmfhsize+bmihsize+width*height;
::ZeroMemory(&bmfh, bmfhsize);
::ZeroMemory(&bmih, bmihsize);
bmfh.bfType=0x4d42;
bmfh.bfSize=filesize;
bmfh.bfReserved1=0;
bmfh.bfReserved2=0;
bmfh.bfOffBits=bmfhsize+bmihsize;
bmih.biSize=bmihsize;
bmih.biWidth=width;
bmih.biHeight=height;
bmih.biPlanes=1;
bmih.biBitCount=32;
bmih.biClrUsed=2;
bmih.biCompression=BI_RGB;//無圧縮形式
bmih.biSizeImage=0;//BI_RGBをセットした場合、0が好ましいとMSDNに書いてあった。
bmih.biXPelsPerMeter=0;
bmih.biYPelsPerMeter=0;
bmih.biClrImportant=0;
MessageBox(NULL,"Debug 1","Debug1",MB_OK);
fwrite(&bmfh,sizeof(unsigned char),bmfhsize,fpt);
fwrite(&bmih,sizeof(unsigned char),bmihsize,fpt);
MessageBox(NULL,"Debug 2","Debug2",MB_OK);
fwrite(&bmp_info.bmBits,1,3*width*height,fpt);
MessageBox(NULL,"Debug 3","Debug3",MB_OK);
fclose(fpt);
DeleteDC(hdc_mem);
CloseClipboard();
}
EndPaint(hWnd, &ps);
break;
}
break;
画像の先頭アドレスがどこにおさめられているのかが
わかりません
fwrite(&bmp_info.bmBits,1,3*width*height,fpt);
がおかしい様なのですがよくわかりません。
よろしくおねがいします。
No.2ベストアンサー
- 回答日時:
こんばんは。
クリップボードから取り出したHBITMAPを、新たに作成したDIBのHBITMAPに複写し、DIBのHBITMAPをセーブに使用します。
以下は32bitの「screen shot.bmp」を作成します。参考程度に。
static void InitHDR(LPBITMAPINFOHEADER pbmih, DWORD width, DWORD height)
{
pbmih->biSize = sizeof(*pbmih);
pbmih->biPlanes = 1;
pbmih->biCompression = BI_BITFIELDS;
pbmih->biBitCount = 32;
pbmih->biWidth = width;
pbmih->biHeight= height;
}
static void InitFields(LPDWORD p)
{
p[0] = 0xff0000;
p[1] = 0xff00;
p[2] = 0xff;
}
static HBITMAP CreateDIBFrom(HBITMAP hBitmap)
{
LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::calloc(1, sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 3)));
BITMAP bitmap;
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
::InitHDR(&pbmi->bmiHeader, bitmap.bmWidth, bitmap.bmHeight);
::InitFields(reinterpret_cast<LPDWORD>(&pbmi->bmiColors));
LPVOID pvBits = NULL;
HBITMAP hDIB = ::CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
if(hDIB)
{
HDC hDCDest = ::CreateCompatibleDC(NULL);
HDC hDCSrc = ::CreateCompatibleDC(NULL);
::SelectObject(hDCDest, hDIB);
::SelectObject(hDCSrc, hBitmap);
::BitBlt(hDCDest, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hDCSrc, 0, 0, SRCCOPY);
::DeleteDC(hDCDest);
::DeleteDC(hDCSrc);
}
::free(pbmi);
return hDIB;
}
static BOOL SaveDIB(LPSTR strFileName, HBITMAP hBitmap)
{
DIBSECTION dib;
::GetObject(hBitmap, sizeof(dib), &dib);
BITMAPFILEHEADER bmfh = {0};
bmfh.bfType= 0x4d42;
bmfh.bfOffBits= sizeof(bmfh) + sizeof(dib.dsBmih) + sizeof(dib.dsBitfields);
bmfh.bfSize= bmfh.bfOffBits + dib.dsBmih.biSizeImage;
FILE* fp = ::fopen(strFileName, "wb");
if(fp == NULL)return FALSE;
::fwrite(&bmfh, sizeof(bmfh), 1, fp);
::fwrite(&dib.dsBmih, sizeof(dib.dsBmih), 1, fp);
::fwrite(dib.dsBitfields, sizeof(dib.dsBitfields), 1, fp);
::fwrite(dib.dsBm.bmBits, dib.dsBmih.biSizeImage, 1, fp);
::fclose(fp);
return TRUE;
}
//ウィンドウプロシージャの中で、
case IDM_SAVE:
if(!::IsClipboardFormatAvailable(CF_BITMAP))
break;
::OpenClipboard(hWnd);
try
{
HBITMAP hBitmap = static_cast<HBITMAP>(::GetClipboardData(CF_BITMAP));
if(hBitmap == NULL)
throw TEXT("クリップボードからビットマップを取れなかった");
HBITMAP hDIB = ::CreateDIBFrom(hBitmap);
if(hDIB == NULL)
throw TEXT("DIBへの変換に失敗した");
const BOOL bResult = ::SaveDIB("screen shot.bmp", hDIB);
::DeleteObject(hDIB);
if(bResult == FALSE)
throw TEXT("セーブに失敗した");
}
catch(LPCTSTR lpctstrError)
{
::MessageBox(hWnd, lpctstrError, TEXT("失敗しました"), IDOK);
}
::CloseClipboard();
break;
こんばんは
ソースコードありがとうございました。
上記ソースコードで実装したところうまくいきました!
まさにもとめていたものそのものです。
本当にありがとうございました!
No.1
- 回答日時:
こんにちは。
チョッと今は時間が御座いませんので、手短に書くと、bmp_info.bmBitsがNULLになっているのではないでしょうか。
クリップボードから取り出したHBITMAPはDDBの筈です。DDBはGetObject()APIで、画像データへのポインタを返さない様になっています。
クリップボードから取り出したHBITMAPと同じ「width x height」を持つDIBSectionを作成し、BitBltにてビットプロック転送をした後、DIBSectionのHBITMAPから画像データへのポインタを取り出してセーブしてみて下さい。
その他、パッと見で気付いた点を挙げますと、
(1)
bmih.biClrUsed=2;
ではなく
bmih.biClrUsed=0;
(2)
bmih.biBitCount=32;
の時
bmih.biCompression=BI_BITFIELDS;
で、RGBQUAD x 3の拡張割り当てと、ビットフィールドの設定が必要です。
bmih.biBitCount=24;
の時
bmih.biCompression=BI_RGB;
とするのが望ましいです。
(3)
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
は不要です。
と言ったところです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- PHP 共通の処理をまとめる方法がわからないのでアドバイスお願いします。 1 2022/12/19 20:20
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- Visual Basic(VBA) vbaの計算 if elseと範囲について 6 2022/11/26 01:49
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
- HTML・CSS ヘッダーの画像にメインエリアがかぶってしまいます 1 2022/11/28 14:06
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語でファイル読み書きを早く...
-
c言語でのfscanfについて
-
構造体のメンバにファイルポイ...
-
fscanfでループしてしまう。
-
テキストファイル内に対して, ...
-
エラーがわかりません、、
-
ファイルからCR/LFを除去したい
-
C言語を用いて、csvファイル内...
-
辞書順にソートしたいのですが...
-
C言語の課題です
-
C言語
-
_popen() のエラー取得
-
[C言語]2つのファイルを用いた...
-
ファイルが読み込めない・・・
-
ファイルに行番号を追加
-
main関数の中をスッキリさせたくて
-
ファイルへの書込み処理が異常...
-
fopenでファイル名に、変数を使...
-
乱数とファイルの入出力の質問...
-
test.csvの内容
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
ファイルへの書込み処理が異常...
-
C言語でファイル読み書きを早く...
-
c言語でのfscanfについて
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
C言語にてXMLファイルから任意...
-
CRC32の計算方法
-
fgets( ) の返り値は何?
-
InternetReadFileを使ったファ...
-
【C言語】ファイルを読み込んで...
-
VisualStudioでのファイルの入...
-
commons-netでのFTP送信について
-
日本語ファイル名のFTPについて
-
fgets関数の利用 c言語
-
C言語でコマンドmvを実行
-
「コマンドライン引数チェック...
-
C言語でセグメンテーションエ...
-
構造体のメンバにファイルポイ...
-
エラー C2664
おすすめ情報