一蓑烟雨任余年 发表于 2020-2-17 14:26

C# 自制电商主图改水印软件

本人新人+小白 第一次发帖,之前学习有关于C# GDI+方面的教程 自己做了一个电商的改水印软件
本人是电商运营 自认为此软件自用改水印功能还是不错,所以分享给大家
如有需要请下载:压缩包包含源码和exe执行文件
软件界面:

软件作用:
修改电商主图水印(主图上的卖点 价格等)可以灵活调整字体颜色 间距 大小 绘制位置 支持批量修改


软件关键源码:(小白一枚 欢迎斧正)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Graphics_Helper
{
    public partial class Form1 : Form
    {
      public Form1()
      {
            InitializeComponent();
      }
      OpenFileDialog ofd;
      private void Button1_Click(object sender, EventArgs e)
      {
            
            ofd = new OpenFileDialog();
            ofd.Title = "请选择文件:";
            string initialDirectory= System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            if (initialDirectory=="")
            {
                initialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Windows);
            }
            ofd.InitialDirectory = initialDirectory;
            ofd.Filter = "图片 | *.jpg; *.jpeg;";
            ofd.Multiselect = true;
            ofd.ShowDialog();

            if (ofd.FileName == "")
            {
                return;
            }
            else
            {
                pcb.Load(ofd.FileNames);
                lblTS.Visible = false;
            }



      }
      int fontx;
      int fonty;
      private void BtnGraphics_Click(object sender, EventArgs e)
      {
            //SaveFileDialog sfd = new SaveFileDialog();
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.ShowDialog();
            if (fbd.SelectedPath == "")
            {
                return;
            }
            Thread th = new Thread(SaveFile);
            th.Start(fbd);
            

      }

      public void SaveFile(object fbd)
      {

            FolderBrowserDialog newfbd = fbd as FolderBrowserDialog;
            
            for (int i = 0; i < ofd.FileNames.Length; i++)
            {

                if (pcb.Image != null)//判断图片是否已加载
                {
                  ReGraphicsWords(Image.FromFile(ofd.FileNames), rectFont.X, rectFont.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
                  Image img = pcb.Image;
                  ImageCodecInfo myImageCodecInfo;
                  System.Drawing.Imaging.Encoder myEncoder;
                  EncoderParameter myEncoderParameter;
                  EncoderParameters myEncoderParameters;
                  myImageCodecInfo = GetEncoderInfo("image/jpeg");
                  myEncoder = System.Drawing.Imaging.Encoder.Quality;
                  myEncoderParameters = new EncoderParameters(1);
                  myEncoderParameter = new EncoderParameter(myEncoder, 100L);
                  myEncoderParameters.Param = myEncoderParameter;

                  //img.Save(@"F:PKX桌面", myImageCodecInfo, myEncoderParameters);
                  img.Save(newfbd.SelectedPath + "\\" + Path.GetFileName(ofd.FileNames), myImageCodecInfo, myEncoderParameters);
                  pcb.Invalidate();
                  g.Dispose();
                  lbResult.Items.Add(newfbd.SelectedPath + "\\" + Path.GetFileName(ofd.FileNames) + " 操作成功");
                }
               
                else
                {
                  MessageBox.Show("未加载图片");
                  return;
                }
            }
            lbResult.Items.Add("共"+ofd.FileNames.Length+"张图片"+"操作成功数:"+lbResult.Items.Count);
      }

      private ImageCodecInfo GetEncoderInfo(string mimeType)
      {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders.MimeType == mimeType)
                  return encoders;
            }
            return null;
      }

      Graphics g;
      Pen p;
      Rectangle rect;
      public void StartGraphics(Point start, Point end, Image img)
      {
            if (img==null)
            {
                MessageBox.Show("请先载入图片");
                return;
            }

            g = Graphics.FromImage(img);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            p = new Pen(currentcolur, 3);
            float width = end.X - start.X;
            float height = end.Y - start.Y;
            g.DrawRectangle(p, start.X, start.Y, width, height);
            //设置要填充矩形的大小
            rect = new Rectangle(start_point.X, start_point.Y, end_point.X - start_point.X, end_point.Y - start_point.Y);
            SolidBrush sb = new SolidBrush(currentcolur);//属于填充矩形的画刷
            g.FillRectangle(sb, rect);
            //把pcb中的iamge转换成一个新的bmp
            pcb.DrawToBitmap(bmp, new Rectangle(pcb.Left, pcb.Top, pcb.Width, pcb.Height));
            currentcolur = bmp.GetPixel(end_point.X, end_point.Y);//获取起始点为坐标颜色

            btnGraphics.BackColor = currentcolur;
            pcb.Invalidate();
            g.Dispose();

      }

      private void Pcb_MouseEnter(object sender, EventArgs e)
      {

            pcb.Cursor = Cursors.Cross;

      }
      Point start_point;//相对于pcb的坐标
      Point end_point;//相对于pcb的坐标
      bool m_down = false;
      private void Pcb_MouseDown(object sender, MouseEventArgs e)
      {//鼠标按下的时候获取坐标初值

            m_down = true;
            if (e.Button == MouseButtons.Left)
            {
                Point pcb_top_point = new Point(0, pcb.Top);

                Point fm_point = this.PointToClient(Control.MousePosition);
                start_point.Y = fm_point.Y - pcb_top_point.Y;//真实的鼠标起始位置要算上窗口鼠标位置+pcb离form.top的距离
                start_point.X = fm_point.X;//X轴无变化
            }



      }

      private void Pcb_MouseUp(object sender, MouseEventArgs e)
      {//鼠标左键放开的时候获取左键最后的坐标

            if (e.Button == MouseButtons.Left)
            {
                Point pcb_top_point = new Point(0, pcb.Top);

                Point fm_point = this.PointToClient(Control.MousePosition);
                end_point.Y = fm_point.Y - pcb_top_point.Y;//真实的鼠标起始位置要算上窗口鼠标位置+pcb离form.top的距离
                end_point.X = fm_point.X;//X轴无变化

                m_down = false;

            }

      }

      Bitmap bmp = new Bitmap(800, 800);
      Color currentcolur;
      private void Pcb_MouseMove(object sender, MouseEventArgs e)
      {
            if (e.Button == MouseButtons.Left)
            {
                if (m_down == false)//如果中途松开了鼠标左键 则放弃绘制
                {
                  return;
                }
                else
                {
                  Point pcb_top_point = new Point(0, pcb.Top);

                  Point fm_point = this.PointToClient(Control.MousePosition);
                  end_point.Y = fm_point.Y - pcb_top_point.Y;//真实的鼠标起始位置要算上窗口鼠标位置+pcb离form.top的距离
                  end_point.X = fm_point.X;//X轴无变化
                  if (end_point.X >= pcb.Width)
                  {
                        lblTS.Text = "填充区域请勿超出图片框";
                        lblTS.Visible = true;
                        end_point.X = pcb.Width-1;
                     
                        
                  }
                  else if (end_point.Y >= pcb.Height)
                  {
                        lblTS.Text = "填充区域请勿超出图片框";
                        lblTS.Visible = true;
                        end_point.Y = pcb.Height-1;
                  }
                  else
                  {

                        lblTS.Visible = false;
                  }
                  StartGraphics(start_point, end_point, pcb.Image);
                }
            }


      }
      ColorDialog cd;
      private void Button1_Click_1(object sender, EventArgs e)
      {
            if (pcb.ImageLocation==null||start_point==null)
            {
                MessageBox.Show("请先导入图片或绘制选区","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                return;
            }
            cd = new ColorDialog();
            
            if (cd.ShowDialog()==DialogResult.OK)
            {
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), start_point.X, start_point.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem), cd.Color);
            }

      }

      private void Form1_Load(object sender, EventArgs e)
      {
            Control.CheckForIllegalCrossThreadCalls = false;
            Thread th = new Thread(GetsysFonts);//创建一个新线程来加载当前系统的字体到cob
            //给间距下拉列表框赋值
            for (int i = -5; i < 11; i++)
            {
                cobSpace.Items.Add(i);
            }
            cobSpace.SelectedItem = 1;
            th.Start();
            txtWords.Text = "活动时间:11月11日0-2点";
            txtWords.Font = new Font("宋体", 12, FontStyle.Italic);
            ColorConverter cc = new ColorConverter();
            txtWords.ForeColor = ColorTranslator.FromHtml("#728893");
            lblPreview.BackColor = Color.Gray;
      }

      /// <summary>
      /// 获取系统已安装的字体
      /// </summary>
      public void GetsysFonts()
      {
            InstalledFontCollection ifc = new InstalledFontCollection();
            FontFamily[] ff = ifc.Families;
            for (int i = 0; i < ff.Length; i++)//给字体下拉框赋值
            {
                cobFont.Items.Add(ff.Name);
            }
            if (cobFont.Items.Contains("微软雅黑"))
            {
                cobFont.SelectedItem = "微软雅黑";
            }
            else
            {
                cobFont.SelectedItem = ff.Name;
            }
            for (int i = 8; i < 72; i++)
            {
                cobFontSize.Items.Add(i);
            }
            
            cobFontSize.SelectedItem = 19;
      }
      
      public static extern int SetTextCharacterExtra(IntPtr hdc, int nCharExtra);

      Rectangle rectFont;
      private void ReGraphicsWords(Image img, int fontx, int fonty, Font ft)
      {
            Color cl;
            if (cd == null)
            {
                cl = Color.Red;
            }
            else
            {
                cl = cd.Color;
            }
            pcb.Image = img;
            StartGraphics(start_point, end_point, pcb.Image);//矩形填充
            g = Graphics.FromImage(pcb.Image);
            IntPtr hdc = g.GetHdc();
            SetTextCharacterExtra(hdc, (int)cobSpace.SelectedItem);
            g.ReleaseHdc();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;


            //矩形的rect已经填充完毕了 如果想改变字符串的位置 需要调整DrawText里rect的位置
            if (rectFont.X == 0)
            {
                rectFont.X = start_point.X;
                rectFont.Y = start_point.Y;
            }
            int RFWidth = rect.Width + Math.Abs(rectFont.X - start_point.X);
            //rectFont = new Rectangle(rectFont.X,rectFont.Y, end_point.X - rectFont.X, end_point.Y - rectFont.Y);
            rectFont = new Rectangle(rectFont.X, rectFont.Y, end_point.X - rectFont.X, end_point.Y - rectFont.Y);
            
            TextRenderer.DrawText(g, txtWords.Text+"   ", ft, rectFont, cl, currentcolur);
            g.Dispose();
      }
      private void ReGraphicsWords(Image img, int fontx, int fonty, Font ft, Color cl)//重载实现改变字体和颜色
      {
            pcb.Image = img;
            StartGraphics(start_point, end_point, pcb.Image);//矩形填充

            g = Graphics.FromImage(pcb.Image);
            
            IntPtr hdc = g.GetHdc();
            SetTextCharacterExtra(hdc, (int)cobSpace.SelectedItem);
            g.ReleaseHdc();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            Color cll;
            if (cl == null)
            {
                cll = Color.Red;
            }
            else
            {
                cll = cl;
            }
            if (rectFont.X==0)
            {
                rectFont.X = start_point.X;
                rectFont.Y = start_point.Y;
            }
            //矩形的rect已经填充完毕了 如果想改变字符串的位置 需要调整DrawText里rect的位置
            //rectFont = new Rectangle(fontx, fonty, end_point.X - start_point.X, end_point.Y - start_point.Y);
            rectFont = new Rectangle(rectFont.X, rectFont.Y, end_point.X - rectFont.X, end_point.Y - rectFont.Y);

            //SolidBrush sb = new SolidBrush(currentcolur);

            //g.DrawString(txtWords.Text, ft,sb, rectFont);

            
            //因为bit的默认backcolor是黑色 因此绘制字体的时候会出现黑边 设置backcolor参数可以解决此问题
            TextRenderer.DrawText(g, txtWords.Text+ "      ", ft, rectFont, cll,currentcolur);
            g.Dispose();
            
      }



      private void Form1_KeyDown(object sender, KeyEventArgs e)
      {
            if (e.KeyData == Keys.Down)
            {

                e.Handled = true;

                rectFont.Y += 2;
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), rectFont.X, rectFont.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
               
            }
            else if (e.KeyData == Keys.Up)
            {
                e.Handled = true;

                rectFont.Y -= 2;
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), rectFont.X, rectFont.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
               
            }
            else if (e.KeyData == Keys.Left)
            {
                e.Handled = true;

                rectFont.X -= 2;
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), rectFont.X-15, rectFont.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
            }
            else if (e.KeyData == Keys.Right)
            {
                e.Handled = true;

                rectFont.X += 2;
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), rectFont.X, rectFont.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
            }

      }

      private void CobFont_SelectedIndexChanged(object sender, EventArgs e)
      {
            Color cl;
            if (cd == null)
            {
                cl = Color.Red;
            }
            else
            {
                cl = cd.Color;
            }

            if (start_point.X != 0)
            {
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), start_point.X, start_point.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem), cl);
            }

      }

      private void FontDialog1_Apply(object sender, EventArgs e)
      {
            MessageBox.Show("Test");
      }

      private void Timer1_Tick(object sender, EventArgs e)
      {

            lblPreview.Text = txtWords.Text;
            lblPreview.Font = new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem);
            Color cl;
            if (cd == null)
            {
                cl = Color.Red;
            }
            else
            {
                cl = cd.Color;
            }
            lblPreview.ForeColor = cl;

      }

      private void TxtWords_MouseClick(object sender, MouseEventArgs e)
      {
            if (txtWords.Text == "活动时间:11月11日0-2点")
            {
                txtWords.Text = "";
                txtWords.Font = new Font("微软雅黑", 12, FontStyle.Regular);
                txtWords.Height = 26;
                txtWords.ForeColor = Color.Black;
            }
      }

      private void Form1_Deactivate(object sender, EventArgs e)
      {
            if (txtWords.Text == "")
            {
                txtWords.Text = "活动时间:11月11日0-2点";
                txtWords.Font = new Font("宋体", 12, FontStyle.Italic);
                txtWords.ForeColor = ColorTranslator.FromHtml("#728893");
            }
      }



      private void CobFontSize_SelectedIndexChanged(object sender, EventArgs e)
      {
            if (start_point.X!=0)
            {
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), start_point.X, start_point.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
                timer1.Interval = 100;//随时预览
                timer1.Start();
            }
            

      }

      private void CobSpace_SelectedIndexChanged(object sender, EventArgs e)
      {
            if (start_point.X!=0)
            {
                ReGraphicsWords(Image.FromFile(pcb.ImageLocation), start_point.X, start_point.Y, new Font(cobFont.SelectedItem.ToString(), (int)cobFontSize.SelectedItem));
                timer1.Interval = 100;//随时预览
                timer1.Start();
            }
      }

      private void BtnRESet_Click(object sender, EventArgs e)
      {
            if (pcb.ImageLocation!=null)
            {
                pcb.Image = Image.FromFile(pcb.ImageLocation);
            }
            
      }

      
    }
}

futureflsl 发表于 2020-2-17 14:59

我给点意见,你这个写的虽然能用,但是不好,为什么呢?代码和窗口代码混在一起,建议封装成类,这样以后也容易扩展和维护

mosou 发表于 2020-2-17 15:46

c# 哪儿学的 有没有推荐的

一蓑烟雨任余年 发表于 2020-2-24 10:24

mosou 发表于 2020-2-17 15:46
c# 哪儿学的 有没有推荐的

赵剑宇基础+传智播客C#进阶

一蓑烟雨任余年 发表于 2020-2-24 10:25

futureflsl 发表于 2020-2-17 14:59
我给点意见,你这个写的虽然能用,但是不好,为什么呢?代码和窗口代码混在一起,建议封装成类,这样以后也 ...

多谢,这个是刚学习时整出来的 代码没改就上传上来了

MrBart 发表于 2020-2-25 10:37

图片多的话,你这个载入太占内存了吧。而且咋显示呢

BE一诺 发表于 2020-3-28 15:55

适合我们学习,谢了

anikduan 发表于 2020-4-14 12:18

安装要密码

猎鹰de盛宴 发表于 2020-4-16 00:29

厉害厉害

MrBart 发表于 2020-8-15 20:26

谢谢分享
页: [1] 2
查看完整版本: C# 自制电商主图改水印软件