No.2ベストアンサー
- 回答日時:
こんばんは。
取りあえず読み込み元がDIB24bit前提と言う事で。グレースケールに変換しながら計算しています。全てを9で割って足さず、全て足してから9で割っています。若しかしたら、間違っているかもしれませんが、其処は御勘弁下さい。
#include<windows.h>
#include<tchar.h>
//固定長配列を数える
#define ArrayCount(a) (sizeof(a) / sizeof(a[0]))
//プロパティ名
const LPCTSTR TSTR_BITMAP = TEXT("bitmap");
//色彩の構造
struct Colors
{
long R;
long G;
long B;
};
//グレースケール変換
static long GetY(long R, long G, long B)
{
return 0.298912 * R + 0.586611 * G + 0.114478 * B;
}
//色彩を設定する
static void SetColor(VOID* p, int x, int y, int strideByte, const Colors* pcolors)
{
BYTE* pByte = (BYTE*)p;
const int pos = (x * 3) + (strideByte * y);
pByte[pos] = pcolors->B;
pByte[pos + 1] = pcolors->G;
pByte[pos + 2] = pcolors->R;
}
//色彩を取り出す
static const Colors GetColor(const VOID* p, int x, int y, int strideByte)
{
const BYTE* pByte = (BYTE*)p;
const int pos = (x * 3) + (strideByte * y);
const Colors colors = {pByte[pos + 2], pByte[pos + 1], pByte[pos]};
return colors;
}
//1スキャン辺りのバイト長を4のn倍調整で計算
static DWORD CalcScanLineByte(const DWORD w, const DWORD bpp)
{
return ((((bpp * w) + 31) / 32) * 4);
}
//範囲外確認
static bool IsInRect(const POINT* ppt, int width, int height)
{
return ppt->x >= 0 && ppt->y >= 0 && ppt->x < width && ppt->y < height;
}
//近傍の計算
static const Colors CalcFilter(const VOID* p, int x, int y, int width, int height, int strideByte)
{
const POINT point[] =
{
{x - 1, y - 1}, {x, y - 1}, {x + 1, y - 1},
{x - 1, y}, {x, y}, {x + 1, y},
{x - 1, y + 1}, {x, y + 1}, {x + 1, y + 1}
};
const int KERNEL_SIZE = ArrayCount(point);
Colors result = {0};
for(int k = 0; k < KERNEL_SIZE; ++k)
{
//範囲外にはみ出た時は、着眼点(中心)の色彩を取る
const int pos = ::IsInRect(&point[k], width, height) ? k : KERNEL_SIZE / 2;
const Colors colors = ::GetColor(p, point[pos].x, point[pos].y, strideByte);
const long Y = ::GetY(colors.R, colors.G, colors.B);
result.R += Y;
result.G += Y;
result.B += Y;
}
//全部足してから9で割る
result.R /= KERNEL_SIZE;
result.G /= KERNEL_SIZE;
result.B /= KERNEL_SIZE;
return result;
}
//滑らかにする
static void Softness(HBITMAP hBitmap, int count = 1/*この数だけ繰り返す*/)
{
BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
const int strideByte = ::CalcScanLineByte(bitmap.bmWidth, 24);
for(int i = 0; i < count; ++i)
{
for(int y = 0; y < bitmap.bmHeight; ++y)
{
for(int x = 0; x < bitmap.bmWidth; ++x)
{
const Colors colors = ::CalcFilter(bitmap.bmBits, x, y, bitmap.bmWidth, bitmap.bmHeight, strideByte);
::SetColor(bitmap.bmBits, x, y, strideByte, &colors);
}
}
}
}
//ウィンドウクラス登録
static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc)
{
WNDCLASSEX wndclass = {sizeof(wndclass)};
wndclass.hCursor= ::LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon= NULL;
wndclass.lpszMenuName= NULL;
wndclass.lpszClassName= szClassName;
wndclass.hbrBackground= (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.hInstance= ::GetModuleHandle(NULL);
wndclass.style= 0;
wndclass.lpfnWndProc= wndProc;
wndclass.cbClsExtra= 0;
wndclass.cbWndExtra= 0;
return ::RegisterClassEx(&wndclass);
}
//ウィンドウを作成して開く
static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h)
{
HINSTANCE hInst = ::GetModuleHandle(NULL);
HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW, szClassName, szTitleName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT, w, h,
NULL, NULL,
hInst, NULL);
return hWnd;
}
//ウィンドウが作られた
static LRESULT OnCreate(HWND hWnd)
{
HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, TEXT("test.bmp")/*読み込みたいファイル名を入れる*/, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
::Softness(hBitmap, 1);
::SetProp(hWnd, TSTR_BITMAP, hBitmap);
return 0;
}
//xボタン
static LRESULT OnClose(HWND hWnd)
{
HBITMAP hBitmap = (HBITMAP)::GetProp(hWnd, TSTR_BITMAP);
::DeleteObject(hBitmap);
::RemoveProp(hWnd, TSTR_BITMAP);
::DestroyWindow(hWnd);
return 0;
}
//ウィンドウが無くなった
static LRESULT OnDestroy(HWND hWnd)
{
::PostQuitMessage(0);
return 0;
}
//再描画
static LRESULT OnPaint(HWND hWnd)
{
HBITMAP hBitmap = (HBITMAP)::GetProp(hWnd, TSTR_BITMAP);
BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
HDC hDC = ::CreateCompatibleDC(NULL);
::SelectObject(hDC, hBitmap);
PAINTSTRUCT ps;
HDC hPaint = ::BeginPaint(hWnd, &ps);
::BitBlt(hPaint, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hDC, 0, 0, SRCCOPY);
::EndPaint(hWnd, &ps);
::DeleteDC(hDC);
return 0;
}
LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE: return ::OnCreate(hWnd);
case WM_CLOSE: return ::OnClose(hWnd);
case WM_DESTROY: return ::OnDestroy(hWnd);
case WM_PAINT: return ::OnPaint(hWnd);
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
TCHAR tstrClassName[] = TEXT("test resize frame");
TCHAR tstrTitleName[] = TEXT("title");
//ウィンドウクラスの登録
::Regist(tstrClassName, &::WndProc);
//ウィンドウを作成して開く
HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600);
//ウィンドウの表示
::ShowWindow(hWnd, SW_SHOW);
//メッセージ回転
while(::GetMessage(&msg, NULL, 0, 0) == TRUE)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
//終了
return msg.wParam;
}
この回答への補足
丁寧に書いていただいて申し訳ないのですが、コンパイルしてみたら、全く問題がなさそうなコーディング箇所にエラーがたくさんでてでて、自力で直そうとしてみたのですが、訳が分からなくなってしまいました。今後も自力で直してみますが、できればアドバイスいただけないでしょうか?
補足日時:2009/05/31 01:46No.3
- 回答日時:
こんにちは。
補足頂きました。思い当たる事を上げると、・ソースファイルの拡張子が.cの場合は関数名に付いている::を消すか、ソースファイルの拡張子を.cppに変更するか(こっちの方が楽)。
・作成するプロジェクトをwin32アプリケーション(window)にする
・リンクエラー対策に
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
comctl32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
winmm.lib
位までリンクしておく、と言った所でしょうか。
No.1
- 回答日時:
>コンパイル可能な状態のプログラム例
そんな都合の良い物はありませんよ。
>プログラム例を参考にして作ろうと、googleなどで検索している
googleで探せば、
・ファイルをメモリに読み込むサンプル
・メモリ上またはファイルにある特定の形式の画像データを展開し、ラスターイメージ(ベタな無圧縮イメージ)のピクセルデータにデコードするサンプル
・2次元配列に格納されたラスターイメージの画像データを平滑化するサンプル
・メモリ上にあるラスターイメージのピクセルデータを、特定の形式の画像データに圧縮してメモリ上またはファイルに保存するサンプル
など、さまざまな「部品」のソースコードがいっぱいヒットするので、それらの部品を組み合わせて自分で作りましょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
【お題】大変な警告
【大喜利】「今このパソコンは大変危険な状態です」という警告メッセージを無視してパソコンを開いたら、こんなことが起こった
-
おすすめの美術館・博物館、教えてください!
美術館・博物館が大好きです。みなさんのおすすめをぜひお聞きしたいです。
-
自分独自の健康法はある?
こうしていると調子がいい!みたいな自分独自の健康法、こだわりはありますか?
-
洋服何着持ってますか?
洋服を減らそうと思っているのですが、何着くらいが相場なのかわかりません。
-
【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
【お題】追い込まれた犯人が咄嗟に言った一言とは?
-
ガウシアンフィルタのCプログラム
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・ことしの初夢、何だった?
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数桁10進数の*桁目だけを抽出...
-
int16_t の _t は何?
-
因数分解を行うプログラムについて
-
C言語 エラーの原因がわからな...
-
「指定されたキャストは有効で...
-
変数の値がおかしくなる
-
(int *)の意味
-
クイックソートの交換回数
-
std::set<int> で、ある値が何...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語で三目並べをするプログラ...
-
多次元配列の構造体の初期化
-
VB6.0でコンピュータ名の取得
-
c言語のリダイレクトによる円...
-
【C++】行列データの読み込み
-
C++で作ったDLLをC#で使うには?
-
標準正規分布の乱数
-
C# 配列時のrefの意味
-
【C++】関数ポインタの使い方
-
構造体のすべての変数を文字列...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
ラップ関数とはどんなものですか?
-
ColorをRGBで指定する方法
-
(int *)の意味
-
足して100になるような乱数のア...
-
シェルピンスキーのギャスケット
-
if と配列の組み合わせ
-
実数の整数部,小数部の取得
-
構造体の勉強中です 合計点の高...
-
「{ } で囲むだけ」は正しい?
-
c言語の配列を使ってサイコロを...
-
式は定数値が必要です」という...
-
acceptをalarmでタイムアウトさ...
-
read関数をノンブロッキングで...
-
std::set<int> で、ある値が何...
おすすめ情報