• ベストアンサー

TIFFを開いてBITMAPで保存する方法

kmb01の回答

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.5

libtiffは触ったことないのですが… No.2補足より >しかし,保存されたビットマップはペイントで開くと, >元がどんなTIFF画像であろうと真っ白になってしまいます. バイナリエディタで開いて正しいBmpファイルが書き込まれているか 確認してください。 No.1補足より、 >nSizeには値は入ってました. >640×480の画像でnSize = 921640でした. >これは多分あってますよね…?? 640*480 =307200 640*480*3=921600 このことからおそらくsizeof(BITMAPINFOHEADER)=40で 各ピクセルに3バイト(24ビット)、 カラーテーブルなしのビットマップを LoadTIFFinDIBが作成したと推測しました。 カラーテーブルなしのため、 >BMPFILEHEADER.bfOffBits = (DWORD)(sizeof( BMPFILEHEADER ) + >BMPINFOHEADER-> >biSize + nColors * sizeof(RGBQUAD)); のnColors * sizeof(RGBQUAD))は余分です。 #通常の24ビットBmpファイルのbfOffBits部分に2^24*4を 加算するとペイントでは真っ白の画面が出力されるようになります。

mkmarimo
質問者

お礼

ご回答ありがとうございます. ご指摘のとおりやってみたらうまくいきました. ありがとうございました.

関連するQ&A

  • bitmap画像の保存がうまくいきません。

    VC++のMFC、ダイアログベースで画像処理のソフトを作っています。 処理した画像を保存したいのですが、「描画できませんでした」というメッセージのでるファイルになってしまい、うまく保存できません。 プログラムは以下のようになっていてピクチャーコントロールの変数をm_pict8にしています。また、画像は24ビットで240×320のものを保存します。 static LONG CalcScanLineByte(const LONG w, const WORD bpp) { return (((bpp * w) + 31) / 32) * 4; } //----------------------------------------------------------- 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); //ピクチャボックスからビットマップを取り出す HBITMAP hBitmap = m_pict8.GetBitmap(); //無いので処理できない if(hBitmap == NULL)return; //ビットマップの情報を取る BITMAP bitmap = {0}; ::GetObject(hBitmap, sizeof(bitmap), &bitmap); //4バイト調整したスキャンラインのサイズ const int iScanLineByte = ::CalcScanLineByte(240, bitmap.bmBitsPixel); //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 = 240; bmif.biHeight= 320; //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); } どこか改善点などありましたら、よろしくお願いいたします。

  • BITMAPFILEHEADER bfSize

    DIBからBMPファイルを作成する処理の一部です。 int nImageSize = pDIB->biSizeImage + (sizeof(RGBQUAD)*dwPaletteSize)+sizeof(BITMAPINFOHEADER); BITMAPFILEHEADER bmpFIH = {0}; bmpFIH.bfType = ( (WORD) ('M' << 8) | 'B'); bmpFIH.bfSize = nImageSize + sizeof(BITMAPFILEHEADER); bmpFIH.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*dwPaletteSize); fwrite(&bmpFIH, 1, sizeof(BITMAPFILEHEADER), pFile); fwrite(pDIB, 1, nImageSize, pFile); fclose(pFile); pFile = 0; BMPファイルは作成されますが、メモリリークします。 bmpFIH.bfSize を 0 またはそれに近い小さな数字にすると、メモリリークは検出されません。 bmpFIH.bfSize はファイルサイズのようですが、これが入っていないと問題でしょうか? また入れるとすればどのような数字を入れるべきでしょうか?(メモリリークの原因も含めて) 宜しくお願いします。 開発環境:VC++ 2008 MFC

  • ファイルへの書き込み処理について

    C++の処理で分からないことがあります。 アドバイスを頂けますようよろしくお願い致します。 以下のプログラムがある場合、 どのような時にエラー処理が実行されるのでしょうか? 例えば、書き込み対象のファイル「C:\WORK\20060508.txt」が既に秀丸等で開かれている状態でもエラーは発生するのでしょうか? TRY { CFile file(strLogFilePath, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate); file.SeekToEnd(); file.Write(strText, strText.GetLength()); file.Close(); } CATCH(CFileException, e) { // エラー処理 } ※補足 strLogFilePath=C:\WORK\20060508.txt strText=テストです。

  • 画像の保存方法。

    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にしています。テキストファイルを保存するプログラムを参考にして作っているので間違っているのだと思います。 画像の保存方法が分かる方がいらっしゃいましたらよろしくお願いいたします。

  • RAID0に高速で書き込む方法(補足2)

    昨日から、たびたび質問させていただいています。 困っているので、教えてください。 下に、ハードディスクにデータを取り込むテストプログラムの一部を載せます。不必要と思われる部分は省かせていただいたので、少々バグが含まれていたり、変数の意味がわからないところがあるかもしれませんが、ご勘弁ください。 CFile file( m_strPath, CFile::modeCreate | CFile::modeReadWrite ); DWORD dwSize; dwSize = 2000000000; file.SetLength( dwSize ); file.SeekToBegin(); DWORD dwTick = GetTickCount(); DWORD aSize = 32 * m_dwSectorsPerCluster * m_dwBytesPerSector; char* buf = new char[ aSize ]; if( buf != NULL ) { DWORD pos; for( pos = 0; pos < dwSize; pos += aSize ) { file.Write( buf, aSize ); } CString str; str.Format( "%d ms for %g MB", GetTickCount() - dwTick, dwSize * 0.001 * 0.001 ); AfxMessageBox( str ); } 最後に書き込んだ大きさと、かかった時間を表示しています。 よろしくお願いします。

  • CFileの使い方を教えてください

    環境はWIN98 VC++6.0 MFCです。 見よう見真似で以下のようにしたら、配列のデータがXXX.txtファイルに保存されました。 それじゃってことで、XXX.txtファイルからデータを取り出し、元通りに配列aa[n]に格納するにはどうすれば良いのですか? そう言うことはやれるのですか? void CAbcDlg::OnButton4() {  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください  CString str;  LPTSTR pszBuf;  long size;   CFile fpw( "XXX.txt", CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive );   for(n=0;n<10;n++){    str=aa[n];    size = str.GetLength();    fpw.Write( &size, sizeof( long ) );    //バッファの確保    pszBuf = str.GetBuffer( size );   //書き込み    fpw.Write( pszBuf, size );   //バッファの開放   str.ReleaseBuffer();  } }

  • Windowsファイルのサイズの問題

    ネットでWindowsのファイルのサイズを計算するサンプルをみています。 ひとつのサンプルをみても、わからないですので、知っている方に質問したいです。 サンプルは WFDはWIN32_FIND_DATA構造体の変数で、 DWORD dwHigh = WFD.nFileSizeHigh; DWORD dwLow = WFD.nFileSizeLow; __int64 nSize; int nLen; char szTemp[MAX_PATH]; char* p; int nCnt; nSize = dwHigh; nSize = (nSize << 32) + 1023; nSize += dwLow; nSize = (nSize >> 10); //KB単位にする いくつの問題があります。 ●ファイルのサイズは、どうしてこんなに計算するの?  どう計算するの? ●(nSize << 32) とnSize >> 10 はなにをやっているの? よろしくお願いします。

  • 連続フレーム画像を保存について

    現在、USBカメラから撮ったフレーム画像を保存するといったプログラムを作成しています。やりたいのはUSBカメラから撮った全てのフレーム画像(例:300フレーム=300枚画像)の保存ですが、今はキーボートを押されるたび画像の保存しかできない状態です。とっても困っています。どうか教えていただけませんか?よろしくお願いします。 while(1){ int v = 0; hr = pGrab -> GetCurrentBuffer( &n, (long *)buffer );// グラブ if( kbhit() ){  getch();//kbhitで取得したキーの破棄  hr = pMC -> Pause(); memset(&bmphdr, 0, sizeof(bmphdr));  bmphdr.bfType = ('M' << 8) | 'B'; bmphdr.bfSize = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER) + n; bmphdr.bfOffBits = sizeof(bmphdr) + sizeof       (BITMAPINFOHEADER);  while(1){ v++; char filename[300];   _snprintf(filename, sizeof(filename),"%d.bmp", v); fh = CreateFile(filename,GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(fh, &bmphdr, sizeof(bmphdr), &nWritten, NULL); WriteFile(fh,&pVideoHeader->bmiHeader, sizeof(BITMAPINFOHEADER), &nWritten, NULL); WriteFile(fh, buffer, n, &nWritten, NULL); CloseHandle(fh); pMC -> Run(); pGrab -> SetBufferSamples(FALSE); if(kbhit()){ break; }  }  printf( "グラブ停止:終了 -- 0 、再開 -- 1 、処理 -- 2\n" );  scanf("%d",&num); }

  • 【MFC】CFileでSeekした位置から値出力したい

    【MFC】CFileでSeekした位置から値出力したい 環境:WindowsXP(SP2)、VisualStudio2005、MFC CFileの「open」を利用して、ファイルをオープンし、 (この時の指定モードはCFile::modeCreate | CFile::modeNoTruncate | CFile::modeWriteです) 指定した位置にseekし、そこへCFileの「Write」で書き込みを行っています。 Seek位置を「SeekToEnd()」で最後へ移動した際は問題ないのですが、途中へSeekし、書き込みを行った際に、そこから上書きされてしまいます。 「挿入」という形で途中にデータを書き込む方法は無いでしょうか? ※特にMFCにこだわっているわけではないので、何かご存知の方がおられましたらご教授お願いいたしますm(__)m

  • MFCを使うための約束事は?

    MFCをつかって、ファイルが存在しているかチェックする プログラムを作ったのですが、上手くいきません。 test.cppは以下のように書いています。 #include "test.h" int _tmain(int argc, _TCHAR* argv[]) { CFile f; CFileException e; if( !f.Open(argv[1], CFile::modeCreate | CFile::modeWrite, &e)) { return 0; } else { f.Close(); return 1; } } test.hは以下のように書いています。 #pragma once #include <afxwin.h> #include <afxext.h> #include <afxole.h> #include <afxdisp.h> どなたかご教授下さい。