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);
}
}
}
}
我给点意见,你这个写的虽然能用,但是不好,为什么呢?代码和窗口代码混在一起,建议封装成类,这样以后也容易扩展和维护 c# 哪儿学的 有没有推荐的 mosou 发表于 2020-2-17 15:46
c# 哪儿学的 有没有推荐的
赵剑宇基础+传智播客C#进阶 futureflsl 发表于 2020-2-17 14:59
我给点意见,你这个写的虽然能用,但是不好,为什么呢?代码和窗口代码混在一起,建议封装成类,这样以后也 ...
多谢,这个是刚学习时整出来的 代码没改就上传上来了 图片多的话,你这个载入太占内存了吧。而且咋显示呢 适合我们学习,谢了 安装要密码 厉害厉害 谢谢分享
页:
[1]
2