C#:小项目-用单元格控件(像素点级别)修改图片

0.

无聊的时候,就想自己想象做一些东西,这不,就想到了这个东西。

准备如下:

  • 一张图片
  • 一个窗体应用项目 (visual studio WF)
  • 主要控件 DataGrideView的使用
  • 怎么想怎么来

想法是这样的:

一张图片的每个像素点,对应到每个单元格(这里使用 DataGrideView控件),想法来源于看到某 ERP系统中的芯片测试数据精确到每个测试点(以万计数)画图且可以查看修改,所以就想知道如何做,虽然不知道它们是用的什么方法,但是下面我就用我的方法来达到类似效果,之后可以举一反三。

1.代码如下:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace btmpToDie {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        Bitmap old; //原来的
        Bitmap bmp; //单元格显示用的
//按钮选取一张图
        private void button1_Click(object sender, System.EventArgs e) {
            var ofd = new OpenFileDialog();
            ofd.Filter = "png|*.png|jpg|*.jpg|bmp|*.bmp";
            if (ofd.ShowDialog() == DialogResult.OK) {
                old = (Bitmap)Bitmap.FromFile(ofd.FileName);
                //太大的话,控件显示延迟太高
                bmp = new Bitmap(100,100);
                Graphics.FromImage(bmp).DrawImage(old, 0, 0, bmp.Width, bmp.Height);
                MessageBox.Show("图片选取成功!");
            }
        }
//按钮-显示到单元格
        private void button2_Click(object sender, System.EventArgs e) {

            //单元格行,列数
            dataGridView1.RowCount = bmp.Height;
            dataGridView1.ColumnCount = bmp.Width;

            //单元格的宽高设置
            for (int x = 0; x < dataGridView1.Columns.Count; x++) {
                dataGridView1.Columns[x].HeaderText = x+"";
                dataGridView1.Columns[x].Width = 10;
                dataGridView1.Columns[x].DividerWidth = 1;
            }
            for (int y = 0; y < dataGridView1.Rows.Count; y++) {
                dataGridView1.Rows[y].HeaderCell.Value = y + "";
                dataGridView1.Rows[y].Height = 10;
                dataGridView1.Rows[y].DividerHeight = 1;
            }
            //行标题列,因为显示不全,所以宽度稍宽
            //dataGridView1.RowHeadersWidth = 50;
            //禁止用户改变单元格宽,高(下面四句都要)
            dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            dataGridView1.AllowUserToResizeColumns = false;
            dataGridView1.AllowUserToResizeRows = false;
            //自定义标题头单元格的样式
            //dataGridView1.EnableHeadersVisualStyles = false;//这句必要
            //DataGridViewCellStyle headers = new DataGridViewCellStyle {
            //    BackColor = Color.Black,
            //    ForeColor = Color.White,
            //    SelectionBackColor = Color.Blue,
            //    Alignment = DataGridViewContentAlignment.MiddleCenter,

            //};
            //dataGridView1.RowHeadersDefaultCellStyle = headers;
            //dataGridView1.ColumnHeadersDefaultCellStyle = headers;
            //隐藏标题头  所以上面的注释了
            dataGridView1.RowHeadersVisible = false;
            dataGridView1.ColumnHeadersVisible = false;
            //数据区单元格样式   背景灰色
            dataGridView1.DefaultCellStyle = new DataGridViewCellStyle {
                BackColor = Color.Gray
            };
            //设置无法直接编辑单元格内容
            dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
            //一次一个像素点操控,不可选择多个单元格(像素)
            //dataGridView1.MultiSelect = false;   //false单个的话,下面双击标签时用current不用select

            
            //显示图片像素点
            for (int y = 0; y < dataGridView1.Rows.Count; y++) {
                for (int x = 0; x < dataGridView1.Columns.Count; x++) {
                    dataGridView1.Rows[y].Cells[x].Style = new DataGridViewCellStyle {
                        BackColor = bmp.GetPixel(x,y)
                    };
                }
            }
            
        }

        //双击标签 ---- 同步保存单元格(像素点)和图片颜色
        int xs = 0; //选中的第一个点的坐标
        int ys = 0;
        int xe = 0; //选中的最后一个点坐标
        int ye = 0;
        private void label1_DoubleClick(object sender, System.EventArgs e) {
            var cd = new ColorDialog();
            if (cd.ShowDialog() == DialogResult.OK) {
                //dataGridView1.CurrentCell.Style.BackColor = cd.Color; //dataGridView1.MultiSelect = false时,用这个
                for (int d = 0; d < dataGridView1.SelectedCells.Count; d++) {
                    DataGridViewCell cell = dataGridView1.SelectedCells[d];
                    cell.Style.BackColor = cd.Color;
                    //按比例修改原图 //注意:直接这样写,那在原图中修改的点不是连续的,所以要手动连续修改
                    int x = cell.ColumnIndex * (old.Width / bmp.Width);
                    int y = cell.RowIndex * (old.Height / bmp.Height);
                    //old.SetPixel(x,y,cd.Color);

                    //连续修改如下:
                    //注意:开始不是 d==0
                    if (d == dataGridView1.SelectedCells.Count - 1) { //开始
                        xs = x;
                        ys = y;
                    }
                    if (d == 0) { //结束
                        xe = x;
                        ye = y;
                    }
                }
                MessageBox.Show(xs +" "+ys + "     "+xe+" "+ye);
                //连续修改整遍选中区域 (进阶:可以在此区域插入其它图片)
                for (int y = ys; y <= ye; y++) {
                    for (int x = xs; x <= xe; x++) {
                        old.SetPixel(x, y, cd.Color);
                    }
                }
                MessageBox.Show("修改完成");
            }
        }

        //同步显示单元格(像素点)颜色    ----单元格点击事件
        private void dataGridView1_CurrentCellChanged(object sender, System.EventArgs e) {
            //标签显示颜色
            label1.BackColor = dataGridView1.CurrentCell.Style.BackColor;
        }


//保存按钮
        //保存用单元格修改好的图片,不用缩放的,而是用原来的old,是因为缩放的bmp清晰度变得模糊了
        private void button3_Click(object sender, System.EventArgs e) {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            old.Save(path+"\\"+"your.png");
            MessageBox.Show("保存成功");
        }
    }
}

效果如下:

1)原图

2)正修改时

3)保存后

4)如果不是用的连续修改解决方案,则效果如下-不理想

所以我们要记录单元格选中的第一个和最后一个,然后转换x,y的值,连续修改原图的像素点。

2.其它问题

我感觉用这个DataGrideView控件 鼠标拖动延迟有点高,不知道如何解决。。。。。。希望有人告知

猜你喜欢

转载自blog.csdn.net/qq_38261174/article/details/86507938