using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace Framework.Common
{
/**/
/// <summary>
/// 名称:图片处理常用操作类
/// 作者:loskiv
/// 创建时间:2009-07-07
/// </summary>
public class ImageUtility
{
/**/
/// <summary>
/// 获取指定mimeType的ImageCodecInfo
/// </summary>
private static ImageCodecInfo GetImageCodecInfo(string mimeType)
{
ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo ici in CodecInfo)
{
if (ici.MimeType == mimeType) return ici;
}
return null;
}
/**/
/// <summary>
/// 获取inputStream中的Bitmap对象
/// </summary>
public static Bitmap GetBitmapFromStream(Stream inputStream)
{
Bitmap bitmap = new Bitmap(inputStream);
return bitmap;
}
/**/
/// <summary>
/// 将Bitmap对象压缩为JPG图片类型
/// </summary>
/// </summary>
/// <param name="bmp">源bitmap对象</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
public static void CompressAsJPG(Bitmap bmp, string saveFilePath, int quality)
{
EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
EncoderParameters ps = new EncoderParameters(1);
ps.Param[0] = p;
bmp.Save(saveFilePath, GetImageCodecInfo("image/jpeg"), ps);
bmp.Dispose();
}
/**/
/// <summary>
/// 将inputStream中的对象压缩为JPG图片类型
/// </summary>
/// <param name="inputStream">源Stream对象</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
public static void CompressAsJPG(Stream inputStream, string saveFilePath, int quality)
{
Bitmap bmp = GetBitmapFromStream(inputStream);
CompressAsJPG(bmp, saveFilePath, quality);
}
/**/
/// <summary>
/// 生成缩略图(JPG 格式)
/// </summary>
/// <param name="inputStream">包含图片的Stream</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="width">缩略图的宽</param>
/// <param name="height">缩略图的高</param>
public static void ThumbAsJPG(Stream inputStream, string saveFilePath, int width, int height)
{
Image image = Image.FromStream(inputStream);
if (image.Width == width && image.Height == height)
{
CompressAsJPG(inputStream, saveFilePath, 80);
}
int tWidth, tHeight, tLeft, tTop;
double fScale = (double)height / (double)width;
if (((double)image.Width * fScale) > (double)image.Height)
{
tWidth = width;
tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);
tLeft = 0;
tTop = (height - tHeight) / 2;
}
else
{
tHeight = height;
tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);
tLeft = (width - tWidth) / 2;
tTop = 0;
}
if (tLeft < 0) tLeft = 0;
if (tTop < 0) tTop = 0;
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
//可以在这里设置填充背景颜色
graphics.Clear(Color.White);
graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));
image.Dispose();
try
{
CompressAsJPG(bitmap, saveFilePath, 80);
}
catch
{
throw;
}
finally
{
bitmap.Dispose();
graphics.Dispose();
}
}
/**/
/// <summary>
/// 将Bitmap对象裁剪为指定JPG文件
/// </summary>
/// <param name="bmp">源bmp对象</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="x">开始坐标x,单位:像素</param>
/// <param name="y">开始坐标y,单位:像素</param>
/// <param name="width">宽度:像素</param>
/// <param name="height">高度:像素</param>
public static void CutAsJPG(Bitmap bmp, string saveFilePath, int x, int y, int width, int height)
{
int bmpW = bmp.Width;
int bmpH = bmp.Height;
if (x >= bmpW || y >= bmpH)
{
CompressAsJPG(bmp, saveFilePath, 80);
return;
}
if (x + width > bmpW)
{
width = bmpW - x;
}
if (y + height > bmpH)
{
height = bmpH - y;
}
Bitmap bmpOut = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bmpOut);
g.DrawImage(bmp, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
g.Dispose();
bmp.Dispose();
CompressAsJPG(bmpOut, saveFilePath, 80);
}
/**/
/// <summary>
/// 将Stream中的对象裁剪为指定JPG文件
/// </summary>
/// <param name="inputStream">源bmp对象</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="x">开始坐标x,单位:像素</param>
/// <param name="y">开始坐标y,单位:像素</param>
/// <param name="width">宽度:像素</param>
/// <param name="height">高度:像素</param>
public static void CutAsJPG(Stream inputStream, string saveFilePath, int x, int y, int width, int height)
{
Bitmap bmp = GetBitmapFromStream(inputStream);
CutAsJPG(bmp, saveFilePath, x, y, width, height);
}
#region 图片水印操作
/**/
/// <summary>
/// 给图片添加图片水印
/// </summary>
/// <param name="inputStream">包含要源图片的流</param>
/// <param name="watermarkPath">水印图片的物理地址</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="mp">水印位置</param>
public static void AddPicWatermarkAsJPG(Stream inputStream, string watermarkPath, string saveFilePath, MarkPosition mp)
{
Image image = Image.FromStream(inputStream);
Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(b);
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, image.Width, image.Height);
AddWatermarkImage(g, watermarkPath, mp, image.Width, image.Height);
try
{
CompressAsJPG(b, saveFilePath, 80);
}
catch { ;}
finally
{
b.Dispose();
image.Dispose();
}
}
/**/
/// <summary>
/// 给图片添加图片水印
/// </summary>
/// <param name="sourcePath">源图片的存储地址</param>
/// <param name="watermarkPath">水印图片的物理地址</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="mp">水印位置</param>
public static void AddPicWatermarkAsJPG(string sourcePath, string watermarkPath, string saveFilePath, MarkPosition mp)
{
if (File.Exists(sourcePath))
{
using (StreamReader sr = new StreamReader(sourcePath))
{
AddPicWatermarkAsJPG(sr.BaseStream, watermarkPath, saveFilePath, mp);
}
}
}
/**/
/// <summary>
/// 给图片添加文字水印
/// </summary>
/// <param name="inputStream">包含要源图片的流</param>
/// <param name="text">水印文字</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="mp">水印位置</param>
public static void AddTextWatermarkAsJPG(Stream inputStream, string text, string saveFilePath, MarkPosition mp)
{
Image image = Image.FromStream(inputStream);
Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(b);
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, image.Width, image.Height);
AddWatermarkText(g, text, mp, image.Width, image.Height);
try
{
CompressAsJPG(b, saveFilePath, 80);
}
catch { ;}
finally
{
b.Dispose();
image.Dispose();
}
}
/**/
/// <summary>
/// 给图片添加文字水印
/// </summary>
/// <param name="sourcePath">源图片的存储地址</param>
/// <param name="text">水印文字</param>
/// <param name="saveFilePath">目标图片的存储地址</param>
/// <param name="mp">水印位置</param>
public static void AddTextWatermarkAsJPG(string sourcePath, string text, string saveFilePath, MarkPosition mp)
{
if (File.Exists(sourcePath))
{
using (StreamReader sr = new StreamReader(sourcePath))
{
AddTextWatermarkAsJPG(sr.BaseStream, text, saveFilePath, mp);
}
}
}
/**/
/// <summary>
/// 添加文字水印
/// </summary>
/// <param name="picture">要加水印的原图像</param>
/// <param name="text">水印文字</param>
/// <param name="mp">添加的位置</param>
/// <param name="width">原图像的宽度</param>
/// <param name="height">原图像的高度</param>
private static void AddWatermarkText(Graphics picture, string text, MarkPosition mp, int width, int height)
{
int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };
Font crFont = null;
SizeF crSize = new SizeF();
for (int i = 0; i < 7; i++)
{
crFont = new Font("Arial", sizes[i], FontStyle.Bold);
crSize = picture.MeasureString(text, crFont);
if ((ushort)crSize.Width < (ushort)width)
break;
}
float xpos = 0;
float ypos = 0;
switch (mp)
{
case MarkPosition.MP_Left_Top:
xpos = ((float)width * (float).01) + (crSize.Width / 2);
ypos = (float)height * (float).01;
break;
case MarkPosition.MP_Right_Top:
xpos = ((float)width * (float).99) - (crSize.Width / 2);
ypos = (float)height * (float).01;
break;
case MarkPosition.MP_Right_Bottom:
xpos = ((float)width * (float).99) - (crSize.Width / 2);
ypos = ((float)height * (float).99) - crSize.Height;
break;
case MarkPosition.MP_Left_Bottom:
xpos = ((float)width * (float).01) + (crSize.Width / 2);
ypos = ((float)height * (float).99) - crSize.Height;
break;
}
StringFormat StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Center;
SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
picture.DrawString(text, crFont, semiTransBrush2, xpos + 1, ypos + 1, StrFormat);
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
picture.DrawString(text, crFont, semiTransBrush, xpos, ypos, StrFormat);
semiTransBrush2.Dispose();
semiTransBrush.Dispose();
}
/**/
/// <summary>
/// 添加图片水印
/// </summary>
/// <param name="picture">要加水印的原图像</param>
/// <param name="waterMarkPath">水印文件的物理地址</param>
/// <param name="mp">添加的位置</param>
/// <param name="width">原图像的宽度</param>
/// <param name="height">原图像的高度</param>
private static void AddWatermarkImage(Graphics picture, string waterMarkPath, MarkPosition mp, int width, int height)
{
Image watermark = new Bitmap(waterMarkPath);
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap();
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
ColorMap[] remapTable = { colorMap };
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
int xpos = 0;
int ypos = 0;
int WatermarkWidth = 0;
int WatermarkHeight = 0;
double bl = 1d;
if ((width > watermark.Width * 4) && (height > watermark.Height * 4))
{
bl = 1;
}
else if ((width > watermark.Width * 4) && (height < watermark.Height * 4))
{
bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
}
else
if ((width < watermark.Width * 4) && (height > watermark.Height * 4))
{
bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
}
else
{
if ((width * watermark.Height) > (height * watermark.Width))
{
bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
}
else
{
bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
}
}
WatermarkWidth = Convert.ToInt32(watermark.Width * bl);
WatermarkHeight = Convert.ToInt32(watermark.Height * bl);
switch (mp)
{
case MarkPosition.MP_Left_Top:
xpos = 10;
ypos = 10;
break;
case MarkPosition.MP_Right_Top:
xpos = width - WatermarkWidth - 10;
ypos = 10;
break;
case MarkPosition.MP_Right_Bottom:
xpos = width - WatermarkWidth - 10;
ypos = height - WatermarkHeight - 10;
break;
case MarkPosition.MP_Left_Bottom:
xpos = 10;
ypos = height - WatermarkHeight - 10;
break;
}
picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
watermark.Dispose();
imageAttributes.Dispose();
}
/**/
/// <summary>
/// 水印的位置
/// </summary>
public enum MarkPosition
{
/**/
/// <summary>
/// 左上角
/// </summary>
MP_Left_Top,
/**/
/// <summary>
/// 左下角
/// </summary>
MP_Left_Bottom,
/**/
/// <summary>
/// 右上角
/// </summary>
MP_Right_Top,
/**/
/// <summary>
/// 右下角
/// </summary>
MP_Right_Bottom
}
#endregion
}
}