//★ Win32 API で Grayscale に変換 前田 稔
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
struct BITMAPINFOHEADER
{
・・・ Image Guid を参照 ・・・
};
public class MyForm : Form
{ Face App;
public MyForm()
{
BackColor = SystemColors.AppWorkspace;
App = new Face();
Width = App.m_bmp.Width;
Height = App.m_bmp.Height+32;
App.InitDib();
App.CopyBmp(App.m_DibDC);
Paint += new PaintEventHandler(MyHandler);
MouseDown += new MouseEventHandler(OnMyMouseDown);
}
private void MyHandler(object sender, PaintEventArgs e)
{
Graphics g;
g = e.Graphics;
if (App.m_bmp == null) Application.Exit();
App.ViewDib(g,0,0);
}
private void OnMyMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) //マウスの左ボタン
{ App.Gray(); }
if (e.Button == MouseButtons.Right) //マウスの右ボタン
{ App.CopyBmp(App.m_DibDC); }
Invalidate();
}
}
//☆ Face Object Class
unsafe class Face
{
public Bitmap m_bmp; // 入力画像
public IntPtr m_Dib; // DIB 画像
public IntPtr m_DibDC; // DIB DC
public byte *dat; // DIB ピクセルデータ
string ImgFile = "";
public const int BI_RGB = 0;
public const int DIB_RGB_COLORS = 0;
public const int SRCCOPY = 0xcc0020;
[DllImport("gdi32.dll")]
・・・ Image Guid を参照 ・・・
// Constructor
public Face()
{
OpenFileDialog opendlg = new OpenFileDialog();
opendlg.Filter = "画像ファイル (*.bmp)|*.bmp|すべてのファイル (*.*)|*.*";
if (opendlg.ShowDialog() == DialogResult.OK)
{ ImgFile = opendlg.FileName; }
try
{ bmp = new Bitmap(ImgFile); }
catch
{ MessageBox.Show("画像ファイルが読めません!", ImgFile);
return;
}
}
// Destructor
~Face()
{ DeleteDC(m_DibDC);
DeleteObject(m_Dib);
}
// m_DibDC(DIB) の画像を描画する
public void ViewDib(Graphics g, int x, int y)
{
if (m_DibDC == null) return;
IntPtr hDC = g.GetHdc();
BitBlt(hDC, x, y, m_bmp.Width, m_bmp.Height, m_DibDC, 0, 0, SRCCOPY);
g.ReleaseHdc(hDC);
}
// hDC ← Bitmap m_bmp イメージデータの転送
public void CopyBmp(IntPtr hDC)
{
IntPtr hBmpSrc = m_bmp.GetHbitmap();
Graphics gdraw = Graphics.FromImage(m_bmp);
IntPtr srcHDC = gdraw.GetHdc();
SelectObject(srcHDC, hBmpSrc);
BitBlt(hDC, 0, 0, m_bmp.Width, m_bmp.Height, srcHDC, 0, 0, SRCCOPY);
DeleteObject(hBmpSrc);
gdraw.ReleaseHdc(srcHDC);
}
//☆ DIB の初期化
unsafe public void InitDib()
{
・・・ Image Guid を参照 ・・・
}
// *dat を Grayscale に変換
public void Gray()
{
byte R, G, B;
int gry;
if (m_bmp == null) return;
CopyBmp(m_DibDC);
for (int y = 0; y < m_bmp.Height; y++)
for (int x = 0; x < m_bmp.Width; x++)
{
B = MAP(x, y, 0);
G = MAP(x, y, 1);
R = MAP(x, y, 2);
gry = (B * 2 + G * 4 + R) / 7;
R = (byte)(gry % 256);
MAP(x, y, R, R, R);
}
}
// *dat(y, x, c) の色を取得
public byte MAP(int x, int y, int c)
{
byte *pt;
pt = dat+(y*m_bmp.Width+x)*4+c;
return *pt;
}
// *dat(y, x) に R,G,B を設定(A はそのまま)
public void MAP(int x, int y, byte r, byte g, byte b)
{
byte *pt;
pt = dat+(y*m_bmp.Width+x)*4;
*pt = b;
*(pt+1)= g;
*(pt+2)= r;
}
}
class image01
{
[STAThread]
public static void Main()
{
MyForm mf = new MyForm();
Application.Run(mf);
}
}
|