
Visual C++6.0でjpgなどのカラーの画像を白黒にして
保存したいのですが、どうすればよいでしょうか?
日本語プログラミング言語「なでしこ」でソースを
組んでみたのですが、やはりインタプリタなので
速いとは言えず290x350の画像で30分程度かかってしまいます。
なでしこでは
画像を表示してその表示されている色を取得して
RGBの形式にし、それを下のURLを参考に
(r*30 + g*59 + b*11)/100しています。
VCでjpgなどを処理するにはどうすればよいでしょうか?
http://www.ne.jp/asahi/nagoya/ahomaro/builder/cp …
No.2ベストアンサー
- 回答日時:
GDI+を利用すると、比較的簡単にJPEGファイルの読み書きができます。
使い方については以下のサイト等を参照して下さい。
http://lamoo.s53.xrea.com/develop/gdiplus/gdiplu …
http://www.kumei.ne.jp/c_lang/sdk4/sdk_335.htm
なおGDI+にはセキュリティ問題があるので、アプリを配布する際はその辺りに配慮する必要があります。
画像ファイルを読み込み、グレースケール画像をJPEGファイルに保存するサンプルは以下のような感じです。
動作確認はVC++.NET 2003(MFC7.1)で行いました。
//--------------------------------------------------
void Convert()
{
// GDI+の初期化
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CBitmap* pBmp = LoadImage(L"d:\\test.jpg");
if (pBmp) {
BITMAP sBitmap;
pBmp->GetBitmap(&sBitmap);
DWORD dwSize = (DWORD)(sBitmap.bmWidthBytes * sBitmap.bmHeight);
BYTE* pBuffer = new BYTE[dwSize];
pBmp->GetBitmapBits(dwSize, pBuffer);
int nOffset = 0;
int nVal = 0;
for (int j = 0; j < sBitmap.bmHeight; j++) {
for (int i = 0;i < sBitmap.bmWidth; i++) {
// pBuffer[nOffset]:青、pBuffer[nOffset + 1]:緑、pBuffer[nOffset + 2]:赤
nVal = (pBuffer[nOffset] * 11 + pBuffer[nOffset + 1] * 59 + pBuffer[nOffset + 2] * 30) / 100;
pBuffer[nOffset + 0] = (BYTE)nVal;
pBuffer[nOffset + 1] = (BYTE)nVal;
pBuffer[nOffset + 2] = (BYTE)nVal;
nOffset += 4; // 32bitカラーは1ピクセル=4バイト
}
nOffset = j * sBitmap.bmWidthBytes;
}
pBmp->SetBitmapBits(dwSize, pBuffer);
SaveJpegImage(L"d:\\test-gr.jpg", *pBmp, 80);
delete pBuffer;
delete pBmp;
}
// GDI+の解放
GdiplusShutdown(gdiplusToken);
}
//--------------------------------------------------
CBitmap* LoadImage(const WCHAR* szFileName)
{
if (!szFileName) return NULL;
CBitmap* pBitmap = NULL;
Bitmap* pGdiBitmap = Bitmap::FromFile(szFileName);
if (pGdiBitmap->GetLastStatus() == Ok) {
HBITMAP hBitmap = NULL;
if (pGdiBitmap->GetHBITMAP(Color(0,0,0), &hBitmap) == Ok) {
pBitmap = new CBitmap();
pBitmap->Attach(hBitmap);
}
}
return pBitmap;
}
//--------------------------------------------------
BOOL SaveJpegImage(const WCHAR* szFileName, const CBitmap& bmp, const int nQuality)
{
if (!szFileName) return FALSE;
// CLSIDの取得
CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
// 品質指定
EncoderParameters encoderParams;
encoderParams.Parameter[0].Guid = EncoderQuality;
encoderParams.Parameter[0].NumberOfValues = 1;
encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParams.Parameter[0].Value = (VOID*)&nQuality;
encoderParams.Count = 1;
Bitmap gdiBmp(bmp, NULL);
if (gdiBmp.Save(szFileName, &clsid, &encoderParams) != Gdiplus::Ok) return FALSE;
return TRUE;
}
//--------------------------------------------------
int GetEncoderClsid(const WCHAR* szFormat, CLSID* pClsid)
{
UINT nNum = 0;
UINT nSize = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&nNum, &nSize);
if (nSize == 0) return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(nSize));
if (!pImageCodecInfo) return -1;
GetImageEncoders(nNum, nSize, pImageCodecInfo);
for (UINT i = 0; i < nNum; ++i) {
if (wcscmp(pImageCodecInfo[i].MimeType, szFormat) == 0) {
*pClsid = pImageCodecInfo[i].Clsid;
free(pImageCodecInfo);
return i;
}
}
free(pImageCodecInfo);
return -1;
}
No.1
- 回答日時:
ヘッダに書いてね。
LPPICTURE m_pJpeg;
BOOL CE_tikanDlg::ReadJpg(CString strJpgPathFileName)
{
// IPictureインターフェイスを初期化
m_pJpeg = NULL;
// JPEGファイルを読み込む
CFile fp;
BOOL bret = fp.Open( strJpgPathFileName, CFile::modeRead);
if( bret == FALSE) {
AfxMessageBox( "jpgがありません");
return FALSE;
}
DWORD dwSize = fp.GetLength();
// グローバル領域を確保
HGLOBAL h = ::GlobalAlloc( GMEM_MOVEABLE, dwSize);
if(h == NULL) {
fp.Close();
AfxMessageBox( "メモリがエラー");
return FALSE;
}
// 領域をロック
void *pBuf = ::GlobalLock( h);
if( pBuf == NULL) {
fp.Close();
::GlobalFree( h);
AfxMessageBox( "GlobalLock失敗");
return FALSE;
}
// ファイルの読み込み
if( fp.Read( pBuf, dwSize) != dwSize) {
fp.Close();
::GlobalUnlock( h);
::GlobalFree( h);
AfxMessageBox("読み込みエラー");
return FALSE;
}
// ファイルのクローズ
fp.Close();
::GlobalUnlock( h);
// IStreamを取得する
LPSTREAM pstm = NULL;
// グローバル領域からIStreamを作成
HRESULT hr =
::CreateStreamOnHGlobal(h, TRUE, &pstm);
if( SUCCEEDED(hr) == FALSE) {
return FALSE;
}
// IPictureのオブジェクトのアドレスを取得
hr = ::OleLoadPicture(pstm, dwSize, FALSE,
IID_IPicture, (LPVOID *)&m_pJpeg);
if( SUCCEEDED( hr) == FALSE || m_pJpeg == NULL)
{
pstm->Release();
AfxMessageBox( "IStream失敗");
return FALSE;
}
// IStreamオブジェクトを開放
pstm->Release();
// 以上までが、jpg読み込み
CPaintDC dc(this);
long hmWidth;
long hmHeight;
m_pJpeg->get_Width(&hmWidth);
m_pJpeg->get_Height(&hmHeight);
CSize size( hmWidth, hmHeight);
// HIMETRIC 単位をデバイス単位に変換
dc.HIMETRICtoDP(&size);
HBITMAP hBmp;
hBmp = CreateCompatibleBitmap(dc, size.cx, size.cy);
// 以上で BMPに変更
で、白黒変更は、自分、知らないので、たぶんここが参考になるっぽい
http://hpcgi1.nifty.com/MADIA/DelphiBBS/wwwlng.c …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- C言語・C++・C# 画像の画素値を変えるC言語のプログラムで指定された画像の中に白い三角形を右上に表示させるにはどのよう 3 2022/10/30 01:16
- PHP 画像ファイルの名前をそのままURLにする 3 2022/10/16 11:18
- Illustrator(イラストレーター) 印刷プレビューに画像が表示されない 3 2022/09/06 14:34
- Windows 8 Route Generator の使い方 1 2023/05/03 00:36
- フリーソフト 倍率自動調整して全画面表示できるフリーの画像ビューアー 1 2023/08/24 10:55
- HTML・CSS リンクバナーのHTMLタグ。画像を変えたり、設置位置を変えるとバナー貼付け側はどう見える? 2 2023/02/01 12:01
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- Android(アンドロイド) 画像に透かしのウォーターマークを追加する方法について 1 2023/06/09 16:43
- Windows 10 Windows10にてjpg形式の画像が開けません 4 2022/08/24 14:37
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fopenでファイル名に、変数を使...
-
エラーがわかりません、、
-
CRC32の計算方法
-
ファイル出力で改行を入れたい!
-
【C言語】ファイルを読み込んで...
-
ファイルの内容の表示
-
C言語 Segmentation fault
-
C言語でファイル読み書きを早く...
-
大量の入力ファイルを扱うとき...
-
datファイルの読み込み
-
C言語の課題です
-
「Aに対するBの割合」と「Aに対...
-
C言語での引数の省略方法
-
DWORDの実際の型は何でしょうか
-
複数桁10進数の*桁目だけを抽出...
-
プログラムでの数字につく”f”の...
-
静的でないメンバ関数の呼び出...
-
Aの値からBの値を除するとは??
-
2進数の足し算(C言語)
-
ある商品のロス率を5%見込み、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
C言語でファイル読み書きを早く...
-
fopenでファイル名に、変数を使...
-
c言語でのfscanfについて
-
ファイルへの書込み処理が異常...
-
ファイル出力で改行を入れたい!
-
fscanfでループしてしまう。
-
C言語にてXMLファイルから任意...
-
テキストファイル内に対して, ...
-
datファイルの読み込み
-
ファイルに行番号を追加
-
大量の入力ファイルを扱うとき...
-
辞書順にソートしたいのですが...
-
InternetReadFileを使ったファ...
-
C言語 連番データの読み込み
-
C言語におけるファイル読み込み...
-
数値のみ抽出(C言語)
-
簡易grep関数ができません。助...
-
VisualStudioでのファイルの入...
-
fgets( ) の返り値は何?
おすすめ情報