画像のヒストグラムを表示します。
Imageに画像データをセット
コード
// // ヒストグラム表示コントロール // komozo // using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Drawing.Imaging; using System.Drawing.Drawing2D; class HistogramView : Panel { enum Channel : int { Alpha, Red, Green, Blue, GrayScale, Count, } private Bitmap image; /// ///線の色配列 /// private Color[] lineColor = new Color[(int)Channel.Count]; /// ///塗りつぶし色配列 /// private Color[] fillColor = new Color[(int)Channel.Count]; /// ///表示/非表示の配列 /// private bool[] visibleChannel = new bool[(int)Channel.Count]; private int[][] iArray = new int[(int)Channel.Count - 1][]; /// ///要素の最大値 /// private float maxCount; /// ///ヒストグラムを取得する画像 /// public Bitmap Image { get { return image; } set { image = value; SetData(); } } /// ///ヒストグラムの表示 グレースケール /// public bool VisibleGrayScale { get { return visibleChannel[(int)Channel.GrayScale]; } set { visibleChannel[(int)Channel.GrayScale] = value; Refresh(); } } /// ///ヒストグラムの表示 アルファチャンネル /// public bool VisibleAlpha { get { return visibleChannel[(int)Channel.Alpha]; } set { visibleChannel[(int)Channel.Alpha] = value; Refresh(); } } /// ///ヒストグラムの表示 赤 /// public bool VisibleRed { get { return visibleChannel[(int)Channel.Red]; } set { visibleChannel[(int)Channel.Red] = value; Refresh(); } } /// ///ヒストグラムの表示 緑 /// public bool VisibleGreen { get { return visibleChannel[(int)Channel.Green]; } set { visibleChannel[(int)Channel.Green] = value; Refresh(); } } /// ///ヒストグラムの表示 青 /// public bool VisibleBlue { get { return visibleChannel[(int)Channel.Blue]; } set { visibleChannel[(int)Channel.Blue] = value; Refresh(); } } /// ///ヒストグラム線の色 グレースケール /// public Color LineColorGrayScale { get { return lineColor[(int)Channel.GrayScale]; } set { lineColor[(int)Channel.GrayScale] = value; this.Refresh(); } } /// ///ヒストグラム線の色 アルファチャンネル /// public Color LineColorAlpha { get { return lineColor[(int)Channel.Alpha]; } set { lineColor[(int)Channel.Alpha] = value; this.Refresh(); } } /// ///ヒストグラム線の色 赤 /// public Color LineColorRed { get { return lineColor[(int)Channel.Red]; } set { lineColor[(int)Channel.Red] = value; this.Refresh(); } } /// ///ヒストグラム線の色 緑 /// public Color LineColorGreen { get { return lineColor[(int)Channel.Green]; } set { lineColor[(int)Channel.Green] = value; this.Refresh(); } } /// ///ヒストグラム線の色 青 /// public Color LineColorBlue { get { return lineColor[(int)Channel.Blue]; } set { lineColor[(int)Channel.Blue] = value; this.Refresh(); } } /// ///ヒストグラム塗りつぶし色 グレースケール /// public Color FillGrayScale { get { return fillColor[(int)Channel.GrayScale]; } set { fillColor[(int)Channel.GrayScale] = value; this.Refresh(); } } /// ///ヒストグラム塗りつぶし色 アルファチャンネル /// public Color FillAlpha { get { return fillColor[(int)Channel.Alpha]; } set { fillColor[(int)Channel.Alpha] = value; this.Refresh(); } } /// ///ヒストグラム塗りつぶし色 赤 /// public Color FillRed { get { return fillColor[(int)Channel.Red]; } set { fillColor[(int)Channel.Red] = value; this.Refresh(); } } /// ///ヒストグラム塗りつぶし色 緑 /// public Color FillGreen { get { return fillColor[(int)Channel.Green]; } set { fillColor[(int)Channel.Green] = value; this.Refresh(); } } /// ///ヒストグラム塗りつぶし色 青 /// public Color FillBlue { get { return fillColor[(int)Channel.Blue]; } set { fillColor[(int)Channel.Blue] = value; this.Refresh(); } } public HistogramView() { SetStyle(ControlStyles.SupportsTransparentBackColor, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //初期値の代入 this.BackColor = Color.White; lineColor[(int)Channel.GrayScale] = Color.FromArgb(100, 127, 127, 127); lineColor[(int)Channel.Alpha] = Color.FromArgb(100, 192, 0, 192); lineColor[(int)Channel.Red] = Color.FromArgb(100, 255, 0, 0); lineColor[(int)Channel.Green] = Color.FromArgb(100, 0, 255, 0); lineColor[(int)Channel.Blue] = Color.FromArgb(100, 0, 0, 255); fillColor[(int)Channel.GrayScale] = Color.FromArgb(60, 127, 127, 127); fillColor[(int)Channel.Alpha] = Color.FromArgb(60, 192, 0, 192); fillColor[(int)Channel.Red] = Color.FromArgb(60, 255, 0, 0); fillColor[(int)Channel.Green] = Color.FromArgb(60, 0, 255, 0); fillColor[(int)Channel.Blue] = Color.FromArgb(60, 0, 0, 255); for (int i = 0; i < (int)Channel.Count; i++) visibleChannel[i] = true; } /// ///画像からヒストグラムのデータ生成 /// private void SetData() { //配列の初期化 for (int i = 0; i < (int)Channel.Count - 1; i++) iArray[i] = new int[256]; if (image == null) { this.Refresh(); return; } //色の要素数 int pixelSize = 0; if (image.PixelFormat == PixelFormat.Format24bppRgb) { pixelSize = 3; } else if (image.PixelFormat == PixelFormat.Format32bppArgb || image.PixelFormat == PixelFormat.Format32bppRgb) { pixelSize = 4; } if (pixelSize == 0) { Bitmap tmp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(image, 0, 0, image.Width, image.Height); } image = tmp; pixelSize = 3; } //ImageをByte配列化 BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); int stride = bmpData.Stride; byte[] bmpByte = new byte[stride * image.Height]; Marshal.Copy(bmpData.Scan0, bmpByte, 0, bmpByte.Length); image.UnlockBits(bmpData); int w = image.Width; int h = image.Height; if (pixelSize == 3) { for (int j = 0; j < h; j++) { for (int i = 0; i < w * pixelSize; i += pixelSize) { int index = (j * stride) + i; iArray[(int)Channel.Red][(bmpByte[index + 2])]++; iArray[(int)Channel.Green][(bmpByte[index + 1])]++; iArray[(int)Channel.Blue][(bmpByte[index + 0])]++; } } } else if (pixelSize == 4) { for (int j = 0; j < h; j++) { for (int i = 0; i < w * pixelSize; i += pixelSize) { int index = (j * stride) + i; iArray[(int)Channel.Alpha][(bmpByte[index + 3])]++; iArray[(int)Channel.Red][(bmpByte[index + 2])]++; iArray[(int)Channel.Green][(bmpByte[index + 1])]++; iArray[(int)Channel.Blue][(bmpByte[index + 0])]++; } } } //各要素の最大値を取得 maxCount = Max(new int[] { Max(iArray[(int)Channel.Alpha]), Max(iArray[(int)Channel.Red]), Max(iArray[(int)Channel.Green]), Max(iArray[(int)Channel.Blue]) }); Refresh(); } /// ///配列から最大値を取得 /// /// /// private int Max(int[] intArray) { int max = 0; for (int i = 0; i < intArray.Length; i++) { max = max < intArray[i] ? intArray[i] : max; } return max; } /// ///描画処理 /// /// protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); if (image != null && 0 < maxCount) { List<PointF>[] PointList = new List<PointF>[(int)Channel.Count]; Pen[] pens = new Pen[(int)Channel.Count]; Brush[] brushs = new Brush[(int)Channel.Count]; //new for (int i = 0; i < (int)Channel.Count; i++) PointList[i] = new List<PointF>(); for (int i = 0; i < (int)Channel.Count; i++) pens[i] = new Pen(lineColor[i], 1); for (int i = 0; i < (int)Channel.Count; i++) brushs[i] = new SolidBrush(fillColor[i]); int width = this.ClientSize.Width; int height = this.ClientSize.Height; pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias; for (int i = 0; i < 256; i++) { float x1, x2, yA, yR, yG, yB; x1 = i * (width / 256f); x2 = (i + 1) * (width / 256f); yA = height - (iArray[(int)Channel.Alpha][i] / maxCount * height); PointList[(int)Channel.Alpha].Add(new PointF(x1, yA)); PointList[(int)Channel.Alpha].Add(new PointF(x2, yA)); yR = height - (iArray[(int)Channel.Red][i] / maxCount * height); PointList[(int)Channel.Red].Add(new PointF(x1, yR)); PointList[(int)Channel.Red].Add(new PointF(x2, yR)); yG = height - (iArray[(int)Channel.Green][i] / maxCount * height); PointList[(int)Channel.Green].Add(new PointF(x1, yG)); PointList[(int)Channel.Green].Add(new PointF(x2, yG)); yB = height - (iArray[(int)Channel.Blue][i] / maxCount * height); PointList[(int)Channel.Blue].Add(new PointF(x1, yB)); PointList[(int)Channel.Blue].Add(new PointF(x2, yB)); PointList[(int)Channel.GrayScale].Add(new PointF(x1, (yR + yG + yB) / 3)); PointList[(int)Channel.GrayScale].Add(new PointF(x2, (yR + yG + yB) / 3)); } for (int i = 0; i < (int)Channel.Count; i++) { if (visibleChannel[i]) { //ポイントを元にパスを作成 GraphicsPath path = new GraphicsPath(); path.AddLines(PointList[i].ToArray()); //塗りつぶし用ポイント var drawPos = new List<PointF>(); drawPos.AddRange(PointList[i]); drawPos.Add(new PointF(width, height)); drawPos.Add(new PointF(0, height)); //描画 pe.Graphics.FillPolygon(brushs[i], drawPos.ToArray(), FillMode.Winding); pe.Graphics.DrawPath(pens[i], path); } } } }}
はじめまして。
返信削除実際にImageに画像データをセットをするにはどう記述をすればいいのでしょうか?
画像ファイルを読み込む
返信削除http://dobon.net/vb/dotnet/graphics/imagefromfile.html