1013 lines
36 KiB
C#
1013 lines
36 KiB
C#
using MAX.Core.Helpers;
|
|
using MAX.Framework.Logger;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
|
|
namespace Store.Framework.Helpers
|
|
{
|
|
public class ImageBuild
|
|
{
|
|
public byte[] Img;
|
|
public int Width = 0, Height = 0;
|
|
public Image InitImage = null;
|
|
public string format = "";
|
|
public int PicQuality = 0;//图片质量
|
|
public bool CanUser
|
|
{
|
|
get { return format == ".jpg" || format == ".png"; }
|
|
}
|
|
|
|
public ImageBuild(byte[] image)
|
|
{
|
|
if (image == null || image.Length == 0)
|
|
return;
|
|
Img = image;
|
|
try
|
|
{
|
|
if (image.Length > 3145728)
|
|
{
|
|
return;
|
|
}
|
|
MemoryStream ms = new MemoryStream(Img);
|
|
InitImage = Image.FromStream(ms);
|
|
var f = GetImageFormat(InitImage, out format);
|
|
ms.Close();
|
|
ms.Dispose();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
NLogger.Instance.Error(e.Message);
|
|
}
|
|
if (InitImage == null)
|
|
return;
|
|
Width = InitImage.Width;
|
|
Height = InitImage.Height;
|
|
}
|
|
/// <summary>
|
|
/// 裁剪为指定大小,不符合则返回null
|
|
/// </summary>
|
|
/// <param name="width"></param>
|
|
/// <param name="height"></param>
|
|
/// <returns></returns>
|
|
public byte[] CutToSize(int width, int height)
|
|
{
|
|
if (InitImage == null)
|
|
return null;
|
|
int w = InitImage.Width;
|
|
int h = InitImage.Height;
|
|
if (w < width || h < height)
|
|
{
|
|
return null;
|
|
}
|
|
int x = 0, y = 0, nw = w, nh = h;
|
|
int tx = 0, ty = 0, tw = width, th = height;
|
|
double f = w * 1.0 / width;
|
|
double t = h * 1.0 / height;
|
|
if (f == t)//无需变化
|
|
{
|
|
}
|
|
else if (f > t)//宽度较大
|
|
{
|
|
x = (int)(((f - t) / 2) * width);
|
|
nw = w - x * 2;
|
|
}
|
|
else//高度较大
|
|
{
|
|
y = (int)((t - f) / 2 * height);
|
|
nh = h - y * 2;
|
|
}
|
|
Rectangle fromR = new Rectangle(x, y, nw, nh);
|
|
Rectangle toR = new Rectangle(tx, ty, tw, th);
|
|
Bitmap pickedImage = new Bitmap(width, height);
|
|
|
|
Graphics pickedG = Graphics.FromImage(pickedImage);
|
|
pickedG.InterpolationMode = InterpolationMode.Low;
|
|
pickedG.SmoothingMode = SmoothingMode.HighSpeed;
|
|
pickedG.DrawImage(InitImage, toR, fromR, GraphicsUnit.Pixel);
|
|
//转图片后转二进制数组
|
|
Image initImagex = (Image)pickedImage.Clone();
|
|
MemoryStream ms = new MemoryStream();
|
|
ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
long quality = 80;
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
initImagex.Save(ms, icc, ep);
|
|
byte[] bytes = ms.ToArray();
|
|
return bytes;
|
|
}
|
|
/// <summary>
|
|
/// 添加线条
|
|
/// </summary>
|
|
/// <param name="img"></param>
|
|
public void AddLineToImage(ref byte[] img)
|
|
{
|
|
MemoryStream ms = new MemoryStream(img);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
ms.Close();
|
|
int width = image.Width;
|
|
int height = image.Height;
|
|
if (width < 100 || height < 100)
|
|
return;
|
|
int r = RandomHelper.GetRandomNumber(100, 256);
|
|
int b = RandomHelper.GetRandomNumber(100, 256);
|
|
int g = RandomHelper.GetRandomNumber(100, 256);
|
|
int h = RandomHelper.GetRandomNumber(1, 10);
|
|
var c = Color.FromArgb(r, g, b);
|
|
for (int i = 0; i < h; i++)
|
|
{
|
|
for (int j = 0; j < height; j++)
|
|
image.SetPixel(i, j, c);
|
|
for (int j = 0; j < width; j++)
|
|
image.SetPixel(j, i, c);
|
|
}
|
|
for (int i = height - h; i < height; i++)
|
|
{
|
|
for (int j = 0; j < width; j++)
|
|
image.SetPixel(j, i, c);
|
|
}
|
|
for (int i = width - h; i < width; i++)
|
|
{
|
|
for (int j = 0; j < height; j++)
|
|
image.SetPixel(i, j, c);
|
|
}
|
|
ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
long quality = 75;
|
|
ms = new MemoryStream();
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
image.Save(ms, icc, ep);
|
|
img = ms.ToArray();
|
|
//FileBase.WriteBytes("1.jpg", bytes);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 在图片四周区域随机选取8*8像素,微调像素值
|
|
/// </summary>
|
|
/// <param name="img"></param>
|
|
public void FineTuningImageToRandomArea(ref byte[] img)
|
|
{
|
|
try
|
|
{
|
|
MemoryStream ms = new MemoryStream(img);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
int iW = image.Width;
|
|
int iH = image.Height;
|
|
if (iW <= 32 || iH <= 32) return;
|
|
int x = 0;
|
|
int y = 0;
|
|
Random rand = new Random();
|
|
int r = rand.Next(1, 4);
|
|
switch (r)
|
|
{
|
|
case 1:
|
|
x = rand.Next(0, iW / 4 - 8);
|
|
y = rand.Next(0, iH - 8);
|
|
break;
|
|
case 2:
|
|
x = rand.Next(iW / 4 - 8, iW - 8);
|
|
y = rand.Next(0, iH / 4 - 8);
|
|
break;
|
|
case 3:
|
|
x = rand.Next(iW / 4 - 8, iW - 8);
|
|
y = rand.Next(3 * iH / 4, iH - 8);
|
|
break;
|
|
case 4:
|
|
x = rand.Next(3 * iW / 4, iW - 8);
|
|
y = rand.Next(iH / 4 - 8, 3 * iH / 4);
|
|
break;
|
|
}
|
|
List<List<PixPoint>> lstlstPixes = new List<List<PixPoint>>();
|
|
int tmpx = x;
|
|
int tmpy = y;
|
|
for (int jj = 0; jj < 4; jj++)
|
|
{
|
|
List<PixPoint> lstPixes = new List<PixPoint>();
|
|
lstPixes.Add(new PixPoint { X = tmpx, Y = tmpy });
|
|
for (int i = 1; i < 8 - jj * 2; i++)
|
|
{
|
|
PixPoint ppx = new PixPoint { X = x, Y = ++tmpy };
|
|
lstPixes.Add(ppx);
|
|
PixPoint ppy = new PixPoint { X = ++tmpx, Y = y };
|
|
lstPixes.Add(ppy);
|
|
}
|
|
lstlstPixes.Add(lstPixes);
|
|
if (jj == 3) break;
|
|
tmpx = ++x;
|
|
tmpy = ++y;
|
|
}
|
|
|
|
for (int jj = 3; jj >= 0; jj--)
|
|
{
|
|
|
|
List<PixPoint> lstPixes = new List<PixPoint>();
|
|
tmpx = ++x;
|
|
tmpy = ++y;
|
|
lstPixes.Add(new PixPoint { X = tmpx, Y = tmpy });
|
|
for (int i = 1; i < 7 - jj * 2; i++)
|
|
{
|
|
PixPoint ppx = new PixPoint { X = x, Y = --tmpy };
|
|
lstPixes.Add(ppx);
|
|
PixPoint ppy = new PixPoint { X = --tmpx, Y = y };
|
|
lstPixes.Add(ppy);
|
|
}
|
|
lstlstPixes[jj].AddRange(lstPixes);
|
|
}
|
|
|
|
int inc = 0;
|
|
foreach (var lstpix in lstlstPixes)
|
|
{
|
|
inc++;
|
|
foreach (var pix in lstpix)
|
|
{
|
|
Color color = image.GetPixel(pix.X, pix.Y);
|
|
int newR, newG, newB;
|
|
newR = color.R + inc > 255 ? 255 : color.R + inc;
|
|
newG = color.G + inc > 255 ? 255 : color.G + inc;
|
|
newB = color.B + inc > 255 ? 255 : color.B + inc;
|
|
var c = Color.FromArgb(newR, newG, newB);
|
|
image.SetPixel(pix.X, pix.Y, c);
|
|
}
|
|
}
|
|
ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
//long quality = 75;
|
|
long quality = PicQuality;//之前固定值 现在改为设置的数值
|
|
ms = new MemoryStream();
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
image.Save(ms, icc, ep);
|
|
img = ms.ToArray();
|
|
//TODO:Need Test
|
|
//image.Dispose();
|
|
ms.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
NLogger.Instance.Error(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输出固定大小图片,背景白色填充,返回JPG格式二进制代码
|
|
/// </summary>
|
|
/// <param name="width"></param>
|
|
/// <param name="height"></param>
|
|
/// <param name="maxSize">最大尺寸KB</param>
|
|
/// <returns></returns>
|
|
public byte[] BuildNewSize(int width, int height, int maxSize, string codePath = "1.jpg")
|
|
{
|
|
if (InitImage == null)
|
|
return null;
|
|
int w = InitImage.Width;
|
|
int h = InitImage.Height;
|
|
int x = 0, y = 0, nw = w, nh = h;
|
|
int tx = 0, ty = 0, tw = width, th = height;
|
|
//先缩放
|
|
if (w <= width && h <= height)//无需缩放
|
|
{
|
|
tx = (width - w) / 2;
|
|
tw = w;
|
|
ty = (height - h) / 2;
|
|
th = h;
|
|
}
|
|
else if (w < width && h > height)
|
|
{
|
|
tx = (width - w) / 2;
|
|
tw = w;
|
|
y = (h - height) / 2;
|
|
nh = height;
|
|
}
|
|
else if (w > width && h < height)
|
|
{
|
|
ty = (height - h) / 2;
|
|
th = h;
|
|
x = (w - width) / 2;
|
|
nw = width;
|
|
}
|
|
else
|
|
{
|
|
double f = w * 1.0 / width;
|
|
double t = h * 1.0 / height;
|
|
if (f == t)//无需变化
|
|
{
|
|
}
|
|
else if (f > t)//宽度较大
|
|
{
|
|
x = (int)(((f - t) / 2) * width);
|
|
nw = w - x * 2;
|
|
}
|
|
else//高度较大
|
|
{
|
|
y = (int)((t - f) / 2 * height);
|
|
nh = h - y * 2;
|
|
}
|
|
}
|
|
Rectangle fromR = new Rectangle(x, y, nw, nh);
|
|
Rectangle toR = new Rectangle(tx, ty, tw, th);
|
|
Bitmap pickedImage = new Bitmap(width, height);
|
|
for (int i = 0; i < pickedImage.Width; i++)
|
|
{
|
|
for (int j = 0; j < pickedImage.Height; j++)
|
|
{
|
|
Color color = Color.FromArgb(255, 255, 255);
|
|
pickedImage.SetPixel(i, j, color);
|
|
}
|
|
}
|
|
Graphics pickedG = Graphics.FromImage(pickedImage);
|
|
pickedG.InterpolationMode = InterpolationMode.Low;
|
|
pickedG.SmoothingMode = SmoothingMode.HighSpeed;
|
|
pickedG.DrawImage(InitImage, toR, fromR, GraphicsUnit.Pixel);
|
|
//转图片后转二进制数组
|
|
Image initImagex = (Image)pickedImage.Clone();
|
|
MemoryStream ms = new MemoryStream();
|
|
ImageCodecInfo icc = GetCodeInfo(codePath);
|
|
|
|
//long quality = maxSize == 1024 ? 75l : 85;
|
|
long quality = PicQuality;//之前固定值 现在改为设置的数值
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
|
|
initImagex.Save(ms, icc, ep);
|
|
byte[] bytes = ms.ToArray();
|
|
if (bytes.Length > maxSize * 1024)
|
|
{
|
|
ms = new MemoryStream();
|
|
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
|
|
initImagex.Save(ms, icc, ep);
|
|
bytes = ms.ToArray();
|
|
}
|
|
if (bytes.Length > maxSize * 1024)
|
|
{
|
|
ms = new MemoryStream();
|
|
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 55L);
|
|
initImagex.Save(ms, icc, ep);
|
|
bytes = ms.ToArray();
|
|
}
|
|
//TODO:Need Test
|
|
//pickedImage.Dispose();
|
|
//pickedG.Dispose();
|
|
//initImagex.Dispose();
|
|
//ms.Close();
|
|
if (bytes.Length > maxSize * 1024)
|
|
{
|
|
return null;
|
|
}
|
|
//ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
//initImagex.Save("22.jpg", icc, ep);
|
|
return bytes;
|
|
}
|
|
/// <summary>
|
|
/// 根据路劲得出图片编码信息
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public ImageCodecInfo GetCodeInfo(string path)
|
|
{
|
|
string exe = path.Split('.')[path.Split('.').Length - 1].ToLower();
|
|
ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
|
|
ImageCodecInfo ici = null, defCodecInfo = null;
|
|
foreach (ImageCodecInfo i in icis)
|
|
{
|
|
if (i.MimeType == "image/jpeg")
|
|
defCodecInfo = i;
|
|
if ((exe == "jpg" || exe == "jpeg") && i.MimeType == "image/jpeg")
|
|
{
|
|
ici = i;
|
|
}
|
|
if (exe == "bmp" && i.MimeType == "image/bmp")
|
|
{
|
|
ici = i;
|
|
}
|
|
if (exe == "png" && i.MimeType == "image/png")
|
|
{
|
|
ici = i;
|
|
}
|
|
if (exe == "gif" && i.MimeType == "image/gif")
|
|
{
|
|
ici = i;
|
|
}
|
|
}
|
|
if (ici == null)
|
|
ici = defCodecInfo;
|
|
return ici;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Image图片格式
|
|
/// </summary>
|
|
/// <param name="_img"></param>
|
|
/// <param name="format"></param>
|
|
/// <returns></returns>
|
|
private System.Drawing.Imaging.ImageFormat GetImageFormat(Image _img, out string format)
|
|
{
|
|
if (_img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
|
|
{
|
|
format = ".jpg";
|
|
return System.Drawing.Imaging.ImageFormat.Jpeg;
|
|
}
|
|
if (_img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
|
|
{
|
|
format = ".gif";
|
|
return System.Drawing.Imaging.ImageFormat.Gif;
|
|
}
|
|
if (_img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
|
|
{
|
|
format = ".png";
|
|
return System.Drawing.Imaging.ImageFormat.Png;
|
|
}
|
|
if (_img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
|
|
{
|
|
format = ".bmp";
|
|
return System.Drawing.Imaging.ImageFormat.Bmp;
|
|
}
|
|
format = string.Empty;
|
|
return null;
|
|
}
|
|
|
|
|
|
#region 随机裁四边--10个像素以内
|
|
public void CutPicture(ref byte[] file)
|
|
{
|
|
MemoryStream ms = new MemoryStream(file);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
|
|
Random radom = new Random();
|
|
int cutPixl = radom.Next(1, 5); //左边切除的像素
|
|
int cutPixr = radom.Next(1, 5); //右边切除的像素
|
|
int cutPixt = radom.Next(1, 5); //顶部切除的像素
|
|
int cutPixb = radom.Next(1, 5); //底部切除的像素
|
|
|
|
Image img = BytesToImage(file);
|
|
int iniWidth = img.Width;
|
|
int iniHeight = img.Height;
|
|
|
|
try
|
|
{
|
|
Bitmap bitmap = StartCutImage(file, cutPixl, cutPixr, iniWidth - cutPixl - cutPixt, iniHeight - cutPixr - cutPixb, iniWidth, iniHeight);
|
|
|
|
image = bitmap;
|
|
|
|
ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
//long quality = 75;
|
|
long quality = PicQuality;//之前固定值 现在改为设置的数值
|
|
ms = new MemoryStream();
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
image.Save(ms, icc, ep);
|
|
// image.Save(ms,ImageFormat.Jpeg);
|
|
file = ms.ToArray();
|
|
//TODO:Need Test
|
|
//img.Dispose();
|
|
//bitmap.Dispose();
|
|
//image.Dispose();
|
|
ms.Close();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 剪裁
|
|
/// </summary>
|
|
/// <param name="b">原始Bitmap</param>
|
|
/// <param name="StartX">开始坐标X</param>
|
|
/// <param name="StartY">开始坐标Y</param>
|
|
/// <param name="iWidth">宽度</param>
|
|
/// <param name="iHeight">高度</param>
|
|
/// <returns>剪裁后的Bitmap</returns>
|
|
public static Bitmap StartCutImage(byte[] bytes, int StartX, int StartY, int iWidth, int iHeight, int iniWidth, int iniHeight)
|
|
{
|
|
Image image = BytesToImage(bytes);
|
|
Bitmap b = new Bitmap(image);
|
|
if (bytes == null) return null;
|
|
try
|
|
{
|
|
Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);//裁剪成小一号的图片
|
|
//Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);//保持原大小,裁剪部分用指定的颜色填充
|
|
Graphics graphics = Graphics.FromImage(bmpOut);
|
|
//graphics.Clear(Color.White);//裁剪部分用指定的颜色填充
|
|
graphics.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
|
|
graphics.Dispose();
|
|
bmpOut = new System.Drawing.Bitmap(bmpOut, iniWidth, iniHeight);//图片保存原始的大小尺寸
|
|
return bmpOut;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 字节数组转换为图片
|
|
/// </summary>
|
|
/// <param name="buffer">字节数组</param>
|
|
/// <returns>图片</returns>
|
|
public static Image BytesToImage(byte[] buffer)
|
|
{
|
|
var ms = new MemoryStream(buffer, 0, buffer.Length);
|
|
Image img = Image.FromStream(ms);
|
|
ms.Dispose();
|
|
return (Image)img;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 图片对象转字节数组
|
|
/// </summary>
|
|
/// <param name="imagePath">图片路径</param>
|
|
/// <returns>图片字节数组</returns>
|
|
private byte[] ImageToBytes(string imagePath)
|
|
{
|
|
var fs = new FileStream(imagePath, FileMode.Open);
|
|
byte[] imgBytes = new byte[fs.Length];
|
|
fs.Read(imgBytes, 0, imgBytes.Length);
|
|
fs.Close();
|
|
return imgBytes;
|
|
//var bf = new BinaryFormatter();
|
|
//bf.Serialize(ms,imagePath);
|
|
//ms.Close();
|
|
//return ms.ToArray();
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 添加文字水印
|
|
public void AddWaterMark(ref byte[] file, string shopName = "")
|
|
{
|
|
MemoryStream ms = new MemoryStream(file);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
|
|
try
|
|
{
|
|
Bitmap bitmap = StartAddWaterMark(file, shopName);
|
|
image = bitmap;
|
|
|
|
ImageCodecInfo icc = GetCodeInfo("1.jpg");
|
|
//long quality = 75;
|
|
long quality = PicQuality;//之前固定值 现在改为设置的数值
|
|
ms = new MemoryStream();
|
|
EncoderParameters ep = new EncoderParameters(1);
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
image.Save(ms, icc, ep);
|
|
file = ms.ToArray();
|
|
//image.Dispose();
|
|
//bitmap.Dispose();
|
|
ms.Close();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
throw;
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检测是否是白底图
|
|
/// </summary>
|
|
/// <param name="bytesImg">图片byte数组</param>
|
|
/// <returns>true-白底图 false-非白底图</returns>
|
|
public static bool CheckImageIsWhiteBackground(byte[] bytesImg)
|
|
{
|
|
MemoryStream ms = new MemoryStream(bytesImg);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
int iWhitePixNum = 0;
|
|
int iTotalPix = 0;
|
|
try
|
|
{
|
|
int iWidth = image.Width;
|
|
int iHeight = image.Height;
|
|
int iInpectWidth = 20;
|
|
//统计三窄边白色像素数量
|
|
for (int i = 0; i < iInpectWidth; i++)
|
|
{
|
|
for (int j = 0; j < iHeight; j++)
|
|
{
|
|
Color cl = image.GetPixel(i, j);
|
|
iTotalPix++;
|
|
if (cl.Name.Equals("ffffffff"))
|
|
{
|
|
iWhitePixNum++;
|
|
}
|
|
}
|
|
}
|
|
for (int i = iWidth - iInpectWidth; i < iWidth; i++)
|
|
{
|
|
for (int j = iInpectWidth; j < iHeight; j++)
|
|
{
|
|
Color cl = image.GetPixel(i, j);
|
|
iTotalPix++;
|
|
if (cl.Name.Equals("ffffffff"))
|
|
{
|
|
iWhitePixNum++;
|
|
}
|
|
}
|
|
}
|
|
for (int i = iInpectWidth; i < iWidth; i++)
|
|
{
|
|
for (int j = 0; j < iInpectWidth; j++)
|
|
{
|
|
Color cl = image.GetPixel(i, j);
|
|
iTotalPix++;
|
|
if (cl.Name.Equals("ffffffff"))
|
|
{
|
|
iWhitePixNum++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
NLogger.Instance.Error(ex);
|
|
}
|
|
finally
|
|
{
|
|
ms.Close();
|
|
image.Dispose();
|
|
}
|
|
//如果三窄边的白色像素数量占比高于85%,则判定为白底图
|
|
return Decimal.Divide(iWhitePixNum, iTotalPix) > (decimal)0.85;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加图片水印
|
|
/// </summary>
|
|
/// <param name="image"></param>
|
|
/// <param name="text"></param>
|
|
/// <param name="rectX">水印开始X坐标(自动扣除图片宽度)</param>
|
|
/// <param name="rectY">水印开始Y坐标(自动扣除图片高度</param>
|
|
/// <param name="opacity">透明度 0-1</param>
|
|
/// <param name="externName">文件后缀名</param>
|
|
/// <returns></returns>
|
|
public void AddLogoWaterMark(ref byte[] file, Image watermark, float opacity, string externName, bool bFill = true)
|
|
{
|
|
MemoryStream ms = new MemoryStream(file);
|
|
var image = (Bitmap)Image.FromStream(ms);
|
|
Bitmap bitmap = new Bitmap(image, image.Width, image.Height); //改为固定
|
|
|
|
Graphics g = Graphics.FromImage(bitmap);
|
|
|
|
//下面定义一个矩形区域
|
|
float rectWidth = watermark.Width + 10;
|
|
float rectHeight = watermark.Height + 10;
|
|
//声明矩形域
|
|
|
|
RectangleF textArea;
|
|
if (bFill)
|
|
{
|
|
textArea = new RectangleF(0, 0, image.Width, image.Height);
|
|
}
|
|
else
|
|
{
|
|
int height = watermark.Height;
|
|
int width = watermark.Width;
|
|
height = 80;
|
|
width = 80;
|
|
textArea = new RectangleF(0, 0, width, height);
|
|
}
|
|
Bitmap w_bitmap = ChangeOpacity(watermark, opacity);
|
|
|
|
g.DrawImage(w_bitmap, 0, 0, 80, 80);
|
|
ms = new MemoryStream();
|
|
//保存图片
|
|
switch (externName)
|
|
{
|
|
case ".jpg":
|
|
bitmap.Save(ms, ImageFormat.Jpeg);
|
|
break;
|
|
case ".gif":
|
|
bitmap.Save(ms, ImageFormat.Gif);
|
|
break;
|
|
case ".png":
|
|
bitmap.Save(ms, ImageFormat.Png);
|
|
break;
|
|
default:
|
|
bitmap.Save(ms, ImageFormat.Jpeg);
|
|
break;
|
|
}
|
|
|
|
file = ms.ToArray();
|
|
ms.Close();
|
|
g.Dispose();
|
|
bitmap.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 改变图片的透明度
|
|
/// </summary>
|
|
/// <param name="img">图片</param>
|
|
/// <param name="opacityvalue">透明度</param>
|
|
/// <returns></returns>
|
|
public Bitmap ChangeOpacity(Image img, float opacityvalue)
|
|
{
|
|
|
|
float[][] nArray ={ new float[] {1, 0, 0, 0, 0},
|
|
new float[] {0, 1, 0, 0, 0},
|
|
new float[] {0, 0, 1, 0, 0},
|
|
new float[] {0, 0, 0, opacityvalue, 0},
|
|
new float[] {0, 0, 0, 0, 1}};
|
|
ColorMatrix matrix = new ColorMatrix(nArray);
|
|
ImageAttributes attributes = new ImageAttributes();
|
|
attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
|
|
Image srcImage = img;
|
|
Bitmap resultImage = new Bitmap(srcImage.Width, srcImage.Height);
|
|
Graphics g = Graphics.FromImage(resultImage);
|
|
g.DrawImage(srcImage, new Rectangle(0, 0, srcImage.Width, srcImage.Height), 0, 0, srcImage.Width, srcImage.Height, GraphicsUnit.Pixel, attributes);
|
|
//g.DrawImage(srcImage, 0, 0, srcImage.Width, srcImage.Height) ;
|
|
//g.DrawImage(srcImage, 0, 0, 80,80);
|
|
g.Dispose();
|
|
attributes.Dispose();
|
|
return resultImage;
|
|
}
|
|
|
|
//private static Font crFont = new Font("微软雅黑", 30, FontStyle.Bold);
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="bytes"></param>
|
|
/// <param name="text">水印文字</param>
|
|
/// <returns></returns>
|
|
public static Bitmap StartAddWaterMark(byte[] bytes, string text = "")
|
|
{
|
|
if (bytes == null) return null;
|
|
Image image = BytesToImage(bytes);
|
|
Bitmap bitmap = new Bitmap(image);
|
|
try
|
|
{
|
|
|
|
int width = bitmap.Width, height = bitmap.Height;
|
|
|
|
Graphics g = Graphics.FromImage(bitmap);
|
|
|
|
g.DrawImage(bitmap, 0, 0);
|
|
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
|
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
|
|
|
g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, width, height, GraphicsUnit.Pixel);
|
|
|
|
Font crFont = new Font("微软雅黑", 30, FontStyle.Bold);
|
|
SizeF crSize = new SizeF();
|
|
crSize = g.MeasureString(text, crFont);
|
|
|
|
//背景位置(去掉了. 如果想用可以自己调一调 位置.)
|
|
//g.FillRectangle(new SolidBrush(Color.FromArgb(200, 255, 255, 255)), (width - crSize.Width) / 2, (height - crSize.Height) / 2, crSize.Width, crSize.Height);
|
|
|
|
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(120, 177, 171, 171));//177, 171, 171
|
|
|
|
|
|
//文字水印随机加在一遍
|
|
Random rdom = new Random();
|
|
int rdLocation = rdom.Next(1, 5);//1:左边 2:右边 3:上边 4:下边
|
|
|
|
if (rdLocation == 1)
|
|
{
|
|
#region 左边
|
|
//将原点移动 到图片中点
|
|
g.TranslateTransform(0, height / 2 + crSize.Height);
|
|
//以原点为中心 转 -45度
|
|
g.RotateTransform(-90);
|
|
|
|
g.DrawString(text, crFont, semiTransBrush, new PointF(0, 0));//文字所加的位置
|
|
#endregion
|
|
}
|
|
else if (rdLocation == 2)
|
|
{
|
|
#region 右边
|
|
//将原点移动 到图片中点
|
|
g.TranslateTransform(width - crSize.Width / 2, height / 2 + crSize.Height);
|
|
//以原点为中心 转 -45度
|
|
g.RotateTransform(-90);
|
|
|
|
g.DrawString(text, crFont, semiTransBrush, new PointF(0, 0));//文字所加的位置
|
|
#endregion
|
|
}
|
|
else if (rdLocation == 3)
|
|
{
|
|
#region 上边
|
|
////将原点移动 到图片中点
|
|
//g.TranslateTransform(width / 2 - crSize.Width, 0);
|
|
////以原点为中心 转 -45度
|
|
//g.RotateTransform(-0);
|
|
|
|
g.DrawString(text, crFont, semiTransBrush, new PointF(width / 2 - crSize.Width / 2, 0));//文字所加的位置
|
|
#endregion
|
|
}
|
|
else if (rdLocation == 4)
|
|
{
|
|
#region 下边
|
|
////将原点移动 到图片中点
|
|
//g.TranslateTransform(width / 2 - crSize.Width, height - crSize.Height * 3);
|
|
////以原点为中心 转 -0度
|
|
////g.RotateTransform(-0);
|
|
|
|
g.DrawString(text, crFont, semiTransBrush, new PointF(width / 2 - crSize.Width / 2, height - crSize.Height));//文字所加的位置
|
|
#endregion
|
|
}
|
|
else
|
|
{
|
|
#region 上边
|
|
g.DrawString(text, crFont, semiTransBrush, new PointF(width / 2 - crSize.Width / 2, 0));//文字所加的位置
|
|
#endregion
|
|
}
|
|
//crFont.Dispose();
|
|
g.Dispose();
|
|
//image.Dispose();
|
|
//semiTransBrush.Dispose();
|
|
////将原点移动 到图片中点
|
|
//g.TranslateTransform(width / 2, height / 2);
|
|
////以原点为中心 转 -45度
|
|
//g.RotateTransform(-45);
|
|
|
|
//g.DrawString(text, crFont, semiTransBrush, new PointF(width / 2 - crSize.Width / 2, 0));//文字所加的位置
|
|
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
NLogger.Instance.Error(e);
|
|
}
|
|
|
|
return bitmap;
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 获取两张图片的相似度
|
|
/// </summary>
|
|
/// <param name="image1">图片1</param>
|
|
/// <param name="image2">图片2</param>
|
|
/// <returns></returns>
|
|
public static string GetSimilarityForTwoImgs(Image image1, Image image2)
|
|
{
|
|
string sImg1Hash = GetHash(image1);
|
|
string sImg2Hash = GetHash(image2);
|
|
return Math.Round(((64.0 * 64.0) - CalcSimularDegree(sImg1Hash, sImg2Hash)) / (64.0 * 64.0), 4) * 100 + "%";
|
|
}
|
|
|
|
private static int CalcSimularDegree(string a, string b)
|
|
{
|
|
if (a.Length != b.Length)
|
|
throw new ArgumentException();
|
|
int count = 0;
|
|
for (int i = 0; i < a.Length; i++)
|
|
{
|
|
if (a[i] != b[i])
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
private static string GetHash(Image sourceImage)
|
|
{
|
|
Image image = ReduceSize(sourceImage);
|
|
byte[] grayValues = ReduceColor(image);
|
|
byte average = CalcAverage(grayValues);
|
|
string sRes = ComputeBits(grayValues, average);
|
|
image.Dispose();
|
|
image = null;
|
|
return sRes;
|
|
}
|
|
|
|
private static string ComputeBits(byte[] grayValues, byte average)
|
|
{
|
|
char[] result = new char[grayValues.Length];
|
|
for (int i = 0; i < grayValues.Length; i++)
|
|
{
|
|
if (grayValues[i] < average)
|
|
result[i] = '0';
|
|
else
|
|
result[i] = '1';
|
|
}
|
|
return new string(result);
|
|
}
|
|
|
|
private static byte CalcAverage(byte[] grayValues)
|
|
{
|
|
int sum = 0;
|
|
for (int i = 0; i < grayValues.Length; i++)
|
|
{
|
|
sum += (int)grayValues[i];
|
|
}
|
|
return System.Convert.ToByte(sum / grayValues.Length);
|
|
}
|
|
|
|
private static byte[] ReduceColor(Image image)
|
|
{
|
|
Bitmap bitmap = new Bitmap(image);
|
|
byte[] grayValues = new byte[image.Width * image.Height];
|
|
|
|
for (int i = 0; i < image.Width; i++)
|
|
{
|
|
for (int j = 0; j < image.Height; j++)
|
|
{
|
|
Color color = bitmap.GetPixel(i, j);
|
|
byte grayValue = (byte)(((color.R * 30 + color.G * 59 + color.B * 11) / 100));
|
|
grayValues[i * image.Width + j] = grayValue;
|
|
}
|
|
}
|
|
bitmap.Dispose();
|
|
return grayValues;
|
|
}
|
|
|
|
private static Image ReduceSize(Image image)
|
|
{
|
|
Image image1 = image.GetThumbnailImage(64, 64, () => {
|
|
return false;
|
|
}, IntPtr.Zero);
|
|
return image1;
|
|
}
|
|
|
|
//byte[] 转换 Bitmap
|
|
public static Bitmap BytesToBitmap(byte[] Bytes)
|
|
{
|
|
MemoryStream stream = null;
|
|
try
|
|
{
|
|
stream = new MemoryStream(Bytes);
|
|
return new Bitmap((Image)new Bitmap(stream));
|
|
}
|
|
catch (ArgumentNullException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
finally
|
|
{
|
|
stream.Close();
|
|
}
|
|
}
|
|
//Bitmap转byte[]
|
|
public static byte[] BitmapToBytes(Bitmap Bitmap)
|
|
{
|
|
MemoryStream ms = null;
|
|
try
|
|
{
|
|
ms = new MemoryStream();
|
|
Bitmap.Save(ms, Bitmap.RawFormat);
|
|
byte[] byteImage = new Byte[ms.Length];
|
|
byteImage = ms.ToArray();
|
|
return byteImage;
|
|
}
|
|
catch (ArgumentNullException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
finally
|
|
{
|
|
ms.Close();
|
|
}
|
|
}
|
|
public static Image ResizeImage(System.Drawing.Image imgToResize, Size size)
|
|
{
|
|
//获取图片宽度
|
|
int sourceWidth = imgToResize.Width;
|
|
//获取图片高度
|
|
int sourceHeight = imgToResize.Height;
|
|
|
|
float nPercent = 0;
|
|
float nPercentW = 0;
|
|
float nPercentH = 0;
|
|
//计算宽度的缩放比例
|
|
nPercentW = ((float)size.Width / (float)sourceWidth);
|
|
//计算高度的缩放比例
|
|
nPercentH = ((float)size.Height / (float)sourceHeight);
|
|
|
|
if (nPercentH < nPercentW)
|
|
nPercent = nPercentH;
|
|
else
|
|
nPercent = nPercentW;
|
|
//期望的宽度
|
|
int destWidth = (int)(sourceWidth * nPercent);
|
|
//期望的高度
|
|
int destHeight = (int)(sourceHeight * nPercent);
|
|
|
|
Bitmap b = new Bitmap(destWidth, destHeight);
|
|
Graphics g = Graphics.FromImage((System.Drawing.Image)b);
|
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
//绘制图像
|
|
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
|
|
g.Dispose();
|
|
return (System.Drawing.Image)b;
|
|
}
|
|
|
|
|
|
class PixPoint
|
|
{
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
}
|
|
}
|
|
}
|