一、Spuria编写目的
昨天晚上因为需要把一些照片的边缘变亮(或者说变浅),突然有了写一个程序去处理的想法。Spuria可以读取一张图片,将图片的边缘部分加亮,然后将处理后的图片保存到用户指定的位置。
Spuria下载地址:http://pan.baidu.com/s/1gdFxIdt

原图片与处理后图片的对比:


二、图片加亮的方法
因为我也没有太多图片处理方面的编程经验,用的方法比较笨,就是逐个像素地处理。
我用的方法以一张图片的左上角为例:

处理后的图片比较大,是本程序的一个缺点。新图片用QQ截图后再保存可以得到一张看上去一样但小得多的图片。
三、界面设计

控件TrackBar:tkbDepth
用来调节图片变量的深度,数值越大,程序就会在图像边缘越大的地区进行渐变处理
控件ProgressBar:pgbTmp
是程序处理图片时临时显示的处理进度条
用户可以单击浏览按钮从磁盘中读取图片,左侧显示原图片,右侧显示当前处理后的图片。
通过tkbDepth将右侧图片调整满意后单击保存按钮将生成后的文件保存到磁盘。
四、程序代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Spuria
{
public partial class SpuriaTool : Form
{
#region 窗体初始化
public SpuriaTool()
{
InitializeComponent();
}
private void SpuriaTool_Load(object sender, EventArgs e)
{
//初始化默认图片
if (pcbLeft.Image != null)
{
//初始化右侧修改后图片:按TrackBar的值进行修改
pcbRight.Image = null;
pcbRight.Image = LightenMargin(
pcbLeft.Image.Clone() as Bitmap, tkbDepth.Value);
}
}
#endregion
#region 控件事件
//读入一张新图片
private void btnBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.AutoUpgradeEnabled = true;
ofd.CheckFileExists = true;
ofd.CheckPathExists = true;
ofd.ReadOnlyChecked = false;
ofd.Multiselect = false;
ofd.FileName = "";
ofd.Filter = "PNG|*.png|BMP|*.bmp|JPG|*.jpg|GIF|*.gif";
ofd.Title = "打开图片";
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
//显示读入图片地址,初始化左侧图片框
txtAddress.Text = ofd.FileName;
pcbLeft.Load(ofd.FileName);
//在右侧图片框中展示修改后的图片
pcbRight.Image = LightenMargin(
pcbLeft.Image.Clone() as Bitmap, 10);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
//将修改后的图片保存到磁盘
private void btnSave_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.OverwritePrompt = true;
sfd.Filter = "PNG|*.png|BMP|*.bmp|JPEG|*.jpeg|GIF|*.gif";
sfd.FileName = string.Concat("Spuria_",
DateTime.Now.Year.ToString("#0000"),
DateTime.Now.Month.ToString("#00"),
DateTime.Now.Day.ToString("#00"),
DateTime.Now.Hour.ToString("#00"),
DateTime.Now.Minute.ToString("#00"),
DateTime.Now.Second.ToString("#00"));
sfd.Title = "保存图片";
if (sfd.ShowDialog() == DialogResult.OK)
{
switch (sfd.FilterIndex)
{
case 0:
{
pcbRight.Image.Save(sfd.FileName,
System.Drawing.Imaging.ImageFormat.Png);
}
break;
case 1:
{
pcbRight.Image.Save(sfd.FileName,
System.Drawing.Imaging.ImageFormat.Bmp);
}
break;
case 2:
{
pcbRight.Image.Save(sfd.FileName,
System.Drawing.Imaging.ImageFormat.Jpeg);
}
break;
case 3:
{
pcbRight.Image.Save(sfd.FileName,
System.Drawing.Imaging.ImageFormat.Gif);
}
break;
default:
break;
}
}
}
//当鼠标从TrackBar上松开时触发
private void tkbDepth_MouseUp(object sender, MouseEventArgs e)
{
if (pcbLeft.Image != null)
{
pcbRight.Image = null;
pcbRight.Image = LightenMargin(
pcbLeft.Image.Clone() as Bitmap, tkbDepth.Value);
}
}
#endregion 控件
#region 相关函数
/// <summary>
/// 将一个Bitmap图片的边缘加亮
/// </summary>
/// <param name="bitmap">原图片</param>
/// <param name="depth">加亮深度</param>
/// <returns>加亮后图片</returns>
public Bitmap LightenMargin(Bitmap bitmap, int depth)
{
//输入合法性检查
if (bitmap == null) return null;
if (depth <= 0) return bitmap;
//显示进度条
pgbTemp.Visible = true;
pgbTemp.Value = 0;
Bitmap result = new Bitmap(bitmap.Width, bitmap.Height);
//minx:横向到边框的最短距离 miny:纵向到边框的最短距离
int minx, miny, mindistance;
float coefficient;
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
minx = i < bitmap.Width - i ? i : bitmap.Width - i;
miny = j < bitmap.Height - j ? j : bitmap.Height - j;
//四个角的情况,作与两边相切半径为depth的四个圆
if (minx <= depth && miny <= depth)
{
mindistance =
(int)Math.Sqrt(
(depth - minx) * (depth - minx) +
(depth - miny) * (depth - miny));
//距离圆心距离小于等于depth则渐变(越远离圆心越淡)
if (mindistance <= depth)
{
coefficient = 1.0f * mindistance / depth;
result.SetPixel(i, j, AdjustBrightness(
bitmap.GetPixel(i, j), coefficient));
}
//距离圆心距离大于depth则置白
else
{
result.SetPixel(i, j, Color.FromArgb(
bitmap.GetPixel(i, j).A, 255, 255, 255));
}
}
//四条边的情况(越靠近边越淡)
else if (minx <= depth || miny <= depth)
{
mindistance = minx < miny ? minx : miny;
coefficient = 1.0f - (1.0f * mindistance / depth);
result.SetPixel(i, j,
AdjustBrightness(bitmap.GetPixel(i, j), coefficient));
}
//图片中心部分的情况(不处理)
else
{
result.SetPixel(i, j, bitmap.GetPixel(i, j));
}
//刷新进度条
pgbTemp.Value = 100 * i / bitmap.Width;
}
}
//函数运行完毕,隐藏进度条
pgbTemp.Visible = false;
return result;
}
/// <summary>
/// 改变一个点的颜色:变亮或变暗
/// </summary>
/// <param name="color">被改变颜色</param>
/// <param name="coefficient">颜色调整系数:-1f时颜色最浅,1f时颜色最深</param>
/// <returns>改变后颜色</returns>
public static Color AdjustBrightness(Color color, float coefficient)
{
if (coefficient < -1f) coefficient = -1f;
if (coefficient > 1f) coefficient = 1f;
float red = (float)color.R;
float green = (float)color.G;
float blue = (float)color.B;
if (coefficient < 0)
{
coefficient = 1 + coefficient;
red *= coefficient;
green *= coefficient;
blue *= coefficient;
}
else
{
red = (255 - red) * coefficient + red;
green = (255 - green) * coefficient + green;
blue = (255 - blue) * coefficient + blue;
}
red = red > 0 ? red : 0;
red = red < 255 ? red : 255;
green = green > 0 ? green : 0;
green = green < 255 ? green : 255;
blue = blue > 0 ? blue : 0;
blue = blue < 255 ? blue : 255;
return Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
}
#endregion
}
}
END
Spuria是一款用于处理图片边缘使之变亮的小工具。它能够读取图片,并通过调节参数来控制边缘亮度的渐变范围,最终保存处理后的图片。
1751

被折叠的 条评论
为什么被折叠?



