ページ 1 / 1
メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月06日(月) 13:56
by マッハ
タイトルの件で質問があります。
【実装したいこと】
メモリから画像のバイナリデータを取得し、画像の取得を試みています
【試したこと】
直接画像変換のやり方が分からなかったので、まずはdatファイルを生成し、それを別途画像ファイルに変換できないかを試そうと考えました。datファイル生成のコードは下記の通りで、一応datファイルは生成できました。
○条件
バイナリデータの先頭アドレス : pImage
画像データ全体(1画像)のアドレス : pImage + sizeof(HOGE)
・ pImageはHOGE型のポインタ
・ HOGEは型の名前
コード:
//この前の段階でpImageには値が格納されています
int size = sizeof(hoge);
FILE *fp;
fp = fopen("binaryData.dat", "wb");
//アサーションチェックは後でいれます
fwrite(pImage, size,1,fp);
fclose(fp);
【確認したいこと】
・当初の目的である、バイナリデータから直接画像ファイルを取得するにはどうすればよいでしょうか?
・「試したこと」で示したdatファイル生成→画像ファイル変換は妥当な方法なのでしょうか。また、上記のコードによるdatファイル生成ロジックは正しいのでしょうか。
Cに熟知していないため初歩的な質問かもしれませんが、どうかよろしくお願いします。
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月06日(月) 14:31
by マッハ
追記
上記でdatファイルが得られたとありますが、ファイル容量が40K程度しかなく正しくファイルが生成されていないと思われます。(得られる画像ファイルは数百K~数Mくらいになる予定です。)
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月06日(月) 22:06
by Math
まず"メモリから画像のバイナリデータを取得..."と言われる”メモリ”の正体は何か?と考えています。普通にはカメラのSD"メモリ”かと思うのですが”HOGE型”画像は撮れない気がする...
コード全体(動かせる状態)を載せて頂ければ大体見当がつくと思いますので宜しければ”コード全体の提示を”お願い致します。
(普通には画像データは”点の集まり”であり点1個が赤、青、緑の(光の)3原色情報を持っていればカラー画像になります。まず”HOGE型”が画像データとどう結びつくのかが分かりません。出来ればそこを詳しく説明いただければ理解の助けになります。)
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月06日(月) 22:34
by みけCAT
マッハ さんが書きました:当初の目的である、バイナリデータから直接画像ファイルを取得するにはどうすればよいでしょうか?
バイナリデータの構造に応じた適切なコードを書き、コンパイルし、実行すればいいでしょう。
マッハ さんが書きました:「試したこと」で示したdatファイル生成→画像ファイル変換は妥当な方法なのでしょうか。また、上記のコードによるdatファイル生成ロジックは正しいのでしょうか。
わかりません。
- 「pImageには値が格納されています」とありますが、有効な値である保証がありません。例えばpImageがNULLだと死ぬ可能性があるでしょう。
- 「HOGEは型の名前」であることは書かれていますが、hogeとは何ですか?
- そもそも生成する「datファイル」が何者かわからないので、そこから画像ファイルに変換できるかわかりません。
- 無駄な中間ファイルを作るのは気持ち悪いので、妥当ではないかもしれません。
- sizeof演算子はsize_t型の値を返します。hogeが大きいと、環境によってはint型ではオーバーフローするかもしれません。
- hogeがポインタまたはポインタを含む構造体である場合、一般にファイルにポインタを書き込むのは再利用できずナンセンスであるとみなされるので、このコードは正しくないでしょう。
もう少し具体的な情報(バイナリデータの構造など)を提示できないでしょうか?
また、画像の書き込みには
libjpegや
libpng(+
zlib)などが使えるかもしれません。
PPM形式の画像なら、ライブラリに頼らなくても簡単に生成できるでしょう。
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 15:01
by マッハ
>MATHさん、みけCATさん
返信ありがとうございます。
いろいろ調べてみた結果、自分が扱っているコードの構造体BITMAPINFOHEADERが
オリジナルではなく、マイクロソフトで解説がされている一般的なものであることが判明しました。
なので目的を改め、下記のコードよりビットマップイメージを取得したいと思います。
【参考にしたサイト】
http://kwmkt.web.fc2.com/contents/c0007.html
【開発環境】
win7(32bit), vs2015 pro
【ソースコード】
コード:
//ヘッダファイル
#include <windef.h>
//画像の4角情報格納用構造体
CornerInfo cornerInfo = {0};
//4角の情報格納(コードはエラーコード)
code = getCornerInfo(&cornerInfo);
//ビットマップヘッダ
BITMAPINFOHEADER *headerInfo = NULL;
//4角の情報を元に画像の加工(加工した画像情報がheaderInfoに格納)
//コードはエラーコード
code = procImage(&cornerInfo, 1, &headerInfo);
//*****(ここから本題)*****
//ビットマップイメージ取得処理
//変数宣言
BITMAPFILEHEADER BmpFileHeader; // ビットマップファイルヘッダ
BITMAPINFOHEADER BmpInfoHeader; // ビットマップ情報ヘッダ
DWORD ImageSize = traped_dib->biSizeImage; // データサイズ
BYTE *pBuffer;
// BITMAPFILEHEADERを設定
memset(&BmpFileHeader, 0x00, sizeof(BmpFileHeader));
BmpFileHeader.bfType = ('M' << 8) | 'B';
BmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ImageSize;
BmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// BITMAPINFOHEADERを設定
memset(&BmpInfoHeader, 0x00, sizeof(BmpInfoHeader));
BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfoHeader.biWidth = traped_dib->biWidth;
BmpInfoHeader.biHeight = traped_dib->biHeight;
BmpInfoHeader.biPlanes = traped_dib->biPlanes;
BmpInfoHeader.biBitCount = traped_dib->biBitCount;
BmpInfoHeader.biCompression = traped_dib->biCompression;
BmpInfoHeader.biSizeImage = traped_dib->biSizeImage;
// 出力ファイルオープン
FILE *fp = NULL;
if (fopen_s(&fp, "sample.bmp", "wb") != 0){
return FALSE;
}
// BITMAPFILEHEADER書き込み
if (fwrite(&BmpFileHeader, sizeof(BmpFileHeader), 1, fp) != 1){
fclose(fp);
return FALSE;
}
// BITMAPINFOHEADER書き込み
if (fwrite(&BmpInfoHeader, sizeof(BmpInfoHeader), 1, fp) != 1){
fclose(fp);
return FALSE;
}
// 画像データ書き込み
if (fwrite(pBuffer, sizeof(BYTE), ImageSize, fp) != (size_t)ImageSize){
fclose(fp);
return FALSE;
}
// 出力ファイルクローズ
fclose(fp);
【解決したいことと生じているエラー】
ヘッダファイル <windef.h>が原因っぽいところまでは検討できたのですが、
下記のエラーの解決に至りませんでした。申し訳ありませんが、こちらの解決策を教えて頂けないでしょうか?
1 error C1189: #error : "No Target Architecture" c:\program files\windows kits\8.0\include\um\winnt.h 146 1 CardSample1
2 IntelliSense: #error ディレクティブ: "No Target Architecture" c:\Program Files\Windows Kits\8.0\Include\um\winnt.h 146 2 CardSample1
3 IntelliSense: 識別子 "PCONTEXT" が定義されていません c:\Program Files\Windows Kits\8.0\Include\um\winnt.h 16006 11 CardSample1
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 17:17
by マッハ
windef.hが原因と考え、windows.hに変えて試しましたが、エラーが頻発してしまいました。これらのヘッダファイルを使用せずに何とかビットマップイメージを取得できればいいのですが・・・
申し訳ありませんが、解決案がありましたらお願いします。
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 19:11
by Math
プログラムには”エントリーポイント・通常はmain・か・WinMain・が必要です・
コード:
#include <stdio.h> /* この行は必ず書く、と覚える */
int main() /* 次からメインのプログラムですよ */
{ /* 中カッコの中がプログラム本体 */
printf("hello, world\n"); /* hello, world と表示して改行する */
return 0; /* プログラムを終了します */} /* ちなみにこれは注釈(コメント)です */
または
コード:
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Hello World!", "MessageBox", MB_OK);
return 0;
}
いまは
Win32Consoleプログラムとしてコンパイルした場合
コード:
D:\z\3g\07\c1>c
D:\z\3g\07\c1>rem コンパイル後リンク
D:\z\3g\07\c1>cl /EHsc c1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
c1.cpp
C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\um\winnt.h(154): fatal error C1189: #error: "No Target Architecture"
D:\z\3g\07\c1>rem 実行結果
D:\z\3g\07\c1>c1.exe
'c1.exe' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
D:\z\3g\07\c1>
Win32Windowsプログラムとしてコンパイルした場合
コード:
D:\z\3g\07\g1>g
D:\z\3g\07\g1>nmake -f g.mak
Microsoft(R) Program Maintenance Utility Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /TP /EHsc /D "_MBCS" /MT /Id:\dxlib /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /W3 g1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
g1.cpp
C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\um\winnt.h(154): fatal error C1189: #error: "No Target Architecture"
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.EXE"' : リターン コード '0x2'
Stop.
D:\z\3g\07\g1>
[/size]
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 19:48
by マッハ
>Mathさん
ご返信ありがとうございます。私の理解力が乏しくて申し訳ないのですが、これはご提示のようにすればwindef.hを用いたソースのコンパイルが可能ということでしょうか。
現在BYTEやDWORDを使わずにビットマップイメージを取得できないかを検討しております。
もし可能でしたら、下記のコードの誤りを修正して頂けますと幸いです。
(上記コメントのコードを一部修正してあります。)
コード:
//ヘッダファイル
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
//main関数
int main(){
//画像の4角情報格納用構造体
CornerInfo cornerInfo = {0};
//4角の情報格納(コードはエラーコード)
code = getCornerInfo(&cornerInfo);
//ビットマップヘッダ
BITMAPINFOHEADER *headerInfo = NULL;
//4角の情報を元に画像の加工(加工した画像情報がheaderInfoに格納)
//コードはエラーコード
code = procImage(&cornerInfo, 1, &headerInfo);
//*****(ここから本題)*****
//ビットマップイメージ取得処理
//変数宣言
BITMAPFILEHEADER BmpFileHeader; // ビットマップファイルヘッダ
BITMAPINFOHEADER BmpInfoHeader; // ビットマップ情報ヘッダ
DWORD ImageSize = headerInfo->biSizeImage; // データサイズ
BYTE *pBuffer;
// BITMAPFILEHEADERを設定
memset(&BmpFileHeader, 0x00, sizeof(BmpFileHeader));
BmpFileHeader.bfType = ('M' << 8) | 'B';
BmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ImageSize;
BmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// BITMAPINFOHEADERを設定
memset(&BmpInfoHeader, 0x00, sizeof(BmpInfoHeader));
BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfoHeader.biWidth = headerInfo->biWidth;
BmpInfoHeader.biHeight = headerInfo->biHeight;
BmpInfoHeader.biPlanes = headerInfo->biPlanes;
BmpInfoHeader.biBitCount = headerInfo->biBitCount;
BmpInfoHeader.biCompression = headerInfo->biCompression;
BmpInfoHeader.biSizeImage = headerInfo->biSizeImage;
// 出力ファイルオープン
FILE *fp = NULL;
if (fopen_s(&fp, "sample.bmp", "wb") != 0){
return FALSE;
}
// BITMAPFILEHEADER書き込み
if (fwrite(&BmpFileHeader, sizeof(BmpFileHeader), 1, fp) != 1){
fclose(fp);
return FALSE;
}
// BITMAPINFOHEADER書き込み
if (fwrite(&BmpInfoHeader, sizeof(BmpInfoHeader), 1, fp) != 1){
fclose(fp);
return FALSE;
}
// 画像データ書き込み
if (fwrite(pBuffer, sizeof(BYTE), ImageSize, fp) != (size_t)ImageSize){
fclose(fp);
return FALSE;
}
// 出力ファイルクローズ
fclose(fp);
}
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 20:07
by usao
>これらのヘッダファイルを使用せずに何とかビットマップイメージを取得できればいいのですが・・・
力技(?)ですが,例えば,BITMAPINFOHEADERやらBITMAPFILEHEADERだとかの必要な部分だけを
それらのヘッダからコピペしてくるのではダメなんでしょうか.
#WORDとかBYTEとかもどこぞでdefineされているはずなので,そこを持って来れば
オフトピック
「No Target Architecture」
とかで検索して,自分の状況に合った話が無いか探してみては
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 20:41
by Math
VS2015Communityを使っています。
コード:
//ヘッダファイル
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <Windows.h>
Windows.hの追加でかなりエラーは減ったのですが 以下のエラーが不明です。何か心当たりはありません?。
1>------ ビルド開始: プロジェクト:Cons7, 構成:Debug Win32 ------
1> c1.cpp
1>d:\z\3g\07\cons7\c1.cpp(12): error C2065: 'CornerInfo': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(12): error C2146: 構文エラー: ';' が、識別子 'cornerInfo' の前に必要です。
1>d:\z\3g\07\cons7\c1.cpp(12): error C2065: 'cornerInfo': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(15): error C2065: 'code': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(15): error C2065: 'cornerInfo': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(15): error C3861: 'getCornerInfo': 識別子が見つかりませんでした
1>d:\z\3g\07\cons7\c1.cpp(22): error C2065: 'code': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(22): error C2065: 'cornerInfo': 定義されていない識別子です。
1>d:\z\3g\07\cons7\c1.cpp(22): error C3861: 'procImage': 識別子が見つかりませんでした
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
[/size]
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 21:08
by マッハ
>usaoさん
返信ありがとうございます。
ご指摘事項について少し調査してみようと思います。
もう少しのようでなかなか遠いですね。
>Mathさん
返信ありがとうございます。
お伝え忘れていたのですが、//*****(ここから本題)*****よりも上部に記載したコードはイメージを持っていただく目的でライブラリにある関数を下に私が簡略化して書いたものです。
ここでお伝えしたかったのは下記2点になります。
・ //*****(ここから本題)*****よりも前の処理でheaderInfoの中に画像情報が格納済
・ //*****(ここから本題)*****よりも後の処理でheaderInfoの情報を用いてビットマップイメージを生成
実際には別途ライブラリを読み込む必要があるので記載したソースでは動作はしません。
(ライブラリは他社のものなので提供ができません。申し訳ありません。)
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 21:24
by Math
了解。ではもういいのですね。
Re: メモリからバイナリデータの取得、ファイル書き込みについて
Posted: 2017年3月07日(火) 21:45
by マッハ
>Mathさん
Mathさんや他のみなさんからのアドバイスを元にいろいろ検討したところ、1)windef.hのエラーになる、2)pBUfferの部分があやしいことがわかりました。一旦僕なりに調査し、疑問点があればそれを明確にした上で質問させていただければと思います。ご丁寧に対応くださりありがとうございました。