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で質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- C言語・C++・C# C言語の質問です。バイナリ形式で保存されたWindows Bitmap形式の画像ファイルを読み込み、 3 2023/07/19 14:58
- C言語・C++・C# 参考にいろいろとc言語、c++言語プログラミングでレジストリーを操作したいのですが、無料配布のc++ 3 2022/12/22 01:49
- C言語・C++・C# プログラム内から、MIDIファイルの一部分だけを再生する方法 1 2023/02/15 11:08
- C言語・C++・C# C言語で移動平均のプログラムを作りたいのですが、数値をファイルから取ってきて計算をするプログラムはど 1 2022/09/29 01:21
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
- C言語・C++・C# C言語 3 2022/10/04 15:07
- Visual Basic(VBA) Access VBAから使用したExcelプロセスを閉じる方法について 4 2022/06/08 17:50
- C言語・C++・C# visual studioでフォームデザインを作成する時のVB.netとC#の違い 2 2023/06/22 03:04
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
#define _CRT_SECURE_NO_WARNIN...
-
PowerShellがうまくいかない
-
C言語 エラーの原因がわからな...
-
ラップ関数とはどんなものですか?
-
C言語のユーザ関数の問題の質問...
-
エラー 添字が付けられた値が、...
-
(int *)の意味
-
入力を待たずにstdinの監視をし...
-
構造体の勉強中です 合計点の高...
-
C言語でif文が予想と違う動きを...
-
if と配列の組み合わせ
-
数値を入力して1からその数値ま...
-
read関数をノンブロッキングで...
-
Pythonについて
-
VB6でAddressOfを使った良いサ...
-
配列変数のポインターが勝手に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
へんな現象
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
if と配列の組み合わせ
-
C言語での奇数の和
-
C言語 配列と関数の練習問題
-
ラップ関数とはどんなものですか?
-
(int *)の意味
-
C言語
-
実数の整数部,小数部の取得
-
足して100になるような乱数のア...
-
卒業研究でよく分からないとこ...
-
数字列を3桁ごとにカンマで区切...
-
c言語
-
std::set<int> で、ある値が何...
-
比較回数と交換回数表示について
おすすめ情報