using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace Dongke.WinForm.Controls.InvoiceLayout.DrawBarcode
{
///
/// 图片操作类
///
public static class ImageHelper
{
#region 平铺
// 水平 左 中 右
// 垂直 上 中 下
///
/// 平铺
///
///
///
///
///
public static Image Tile(Image image, Size size, ContentAlignment alignment = ContentAlignment.TopLeft)
{
Image targetImage = new Bitmap(size.Width, size.Height);
Tile(image, targetImage, null, alignment);
return targetImage;
}
///
/// 平铺
///
///
///
///
///
public static void Tile(Image image, Image targetImage, Rectangle? rectangle = null,
ContentAlignment alignment = ContentAlignment.TopLeft)
{
if (rectangle == null)
{
rectangle = new Rectangle(0, 0, targetImage.Width, targetImage.Height);
}
else
{
rectangle = Rectangle.Intersect(rectangle.Value,
new Rectangle(0, 0, targetImage.Width, targetImage.Height));
if (rectangle.Value.IsEmpty)
{
return;
}
}
using (Graphics graphics = Graphics.FromImage(targetImage))
{
Tile(image, graphics, rectangle.Value, alignment);
}
}
///
/// 平铺
///
///
///
///
///
public static void Tile(Image image, Graphics graphics, Rectangle rectangle,
ContentAlignment alignment = ContentAlignment.TopLeft)
{
using (TextureBrush brush = new TextureBrush(image))
{
SetGraphicsHighQuality(graphics);
brush.WrapMode = WrapMode.Tile;
//if (alignment == ContentAlignment.TopLeft)
//{
// graphics.FillRectangle(brush, rectangle);
//}
//else
{
int x = 0;
int y = 0;
switch (alignment)
{
case ContentAlignment.TopCenter:
x = GetCenter(image.Width, rectangle.Width);
break;
case ContentAlignment.TopRight:
x = (rectangle.Width % image.Width) - image.Width;
break;
case ContentAlignment.MiddleLeft:
y = GetCenter(image.Height, rectangle.Height);
break;
case ContentAlignment.MiddleCenter:
x = GetCenter(image.Width, rectangle.Width);
y = GetCenter(image.Height, rectangle.Height);
break;
case ContentAlignment.MiddleRight:
x = (rectangle.Width % image.Width) - image.Width;
y = GetCenter(image.Height, rectangle.Height);
break;
case ContentAlignment.BottomLeft:
y = (rectangle.Height % image.Height) - image.Height;
break;
case ContentAlignment.BottomCenter:
x = GetCenter(image.Width, rectangle.Width);
y = (rectangle.Height % image.Height) - image.Height;
break;
case ContentAlignment.BottomRight:
x = (rectangle.Width % image.Width) - image.Width;
y = (rectangle.Height % image.Height) - image.Height;
break;
default:
break;
}
Rectangle rect = new Rectangle(0, 0,
(x < 0 ? rectangle.Width - x : rectangle.Width),
(y < 0 ? rectangle.Height - y : rectangle.Height));
using (Bitmap tmp = new Bitmap(rect.Width, rect.Height))
{
using (Graphics tmpg = Graphics.FromImage(tmp))
{
SetGraphicsHighQuality(tmpg);
tmpg.FillRectangle(brush, rect);
Rectangle rectImage = new Rectangle(Math.Abs(x), Math.Abs(y),
rectangle.Width,
rectangle.Height);
graphics.DrawImage(tmp, rectangle.X, rectangle.Y, rectImage, GraphicsUnit.Pixel);
}
}
}
}
}
private static int GetCenter(int size1, int size2)
{
int t = (size2 - size1);
if (t > 0)
{
return ((t / 2) % size1) - size1;
}
else if (t < 0)
{
return (t / 2);
}
return 0;
}
#endregion
#region 拉伸
///
/// 拉伸
///
///
///
///
public static Image Stretch(Image image, Size size)
{
//Image targetImage = new Bitmap(image, size);
Image targetImage = new Bitmap(size.Width, size.Height);
Stretch(image, targetImage);
return targetImage;
}
///
/// 拉伸
///
///
///
///
public static void Stretch(Image image, Image targetImage, Rectangle? rectangle = null)
{
if (rectangle == null)
{
rectangle = new Rectangle(0, 0, targetImage.Width, targetImage.Height);
}
else
{
rectangle = Rectangle.Intersect(rectangle.Value,
new Rectangle(0, 0, targetImage.Width, targetImage.Height));
if (rectangle.Value.IsEmpty)
{
return;
}
}
using (Graphics graphics = Graphics.FromImage(targetImage))
{
Stretch(image, graphics, rectangle.Value);
}
}
///
/// 拉伸
///
///
///
///
public static void Stretch(Image image, Graphics graphics, Rectangle rectangle)
{
SetGraphicsHighQuality(graphics);
graphics.DrawImage(image, rectangle);
}
#endregion
#region 缩放(按比例)
///
/// 缩放(按比例)类型
///
public enum ZoomType
{
///
/// 自适应
///
Adaptive = 1,
///
/// 比例填充(超出部分居中)
///
Filled,
///
/// 按宽显示(超出部分居中)
///
WidthRatio,
///
/// 按高显示(超出部分居中)
///
HeightRatio,
}
private static void ZoomWidth(Image image, Graphics graphics, Rectangle rectangle)
{
decimal ratio = rectangle.Width * 1m / image.Width;
int height = (int)(image.Height * ratio);
Rectangle rect = new Rectangle(0, 0, rectangle.Width, height);
//using (Image tmp = Stretch(image, rect.Size))
{
SetGraphicsHighQuality(graphics);
if (height > rectangle.Height)
{
rect.Width = image.Width;
rect.Height = (int)(rectangle.Height / ratio);
rect.Y = (image.Height - rect.Height) / 2;
graphics.DrawImage(image, rectangle, rect, GraphicsUnit.Pixel);
}
else
{
rect.X = rectangle.X;
rect.Y = rectangle.Y + (rectangle.Height - height) / 2;
graphics.DrawImage(image, rect);
}
}
}
private static void ZoomHeight(Image image, Graphics graphics, Rectangle rectangle)
{
decimal ratio = rectangle.Height * 1m / image.Height;
int width = (int)(image.Width * ratio);
Rectangle rect = new Rectangle(0, 0, width, rectangle.Height);
//using (Image tmp = Stretch(image, rect.Size))
{
SetGraphicsHighQuality(graphics);
if (width > rectangle.Width)
{
rect.Height = image.Height;
rect.Width = (int)(rectangle.Width / ratio);
rect.X = (image.Width - rect.Width) / 2;
graphics.DrawImage(image, rectangle, rect, GraphicsUnit.Pixel);
}
else
{
rect.X = rectangle.X + (rectangle.Width - width) / 2;
rect.Y = rectangle.Y;
graphics.DrawImage(image, rect);
}
}
}
///
/// 缩放(按比例)
///
///
///
///
///
public static Image Zoom(Image image, Size size, ZoomType type = ZoomType.Adaptive)
{
//Image targetImage = new Bitmap(image, size);
Image targetImage = new Bitmap(size.Width, size.Height);
Zoom(image, targetImage, null, type);
return targetImage;
}
///
/// 缩放(按比例)
///
///
///
///
///
public static void Zoom(Image image, Image targetImage, Rectangle? rectangle = null,
ZoomType type = ZoomType.Adaptive)
{
if (rectangle == null)
{
rectangle = new Rectangle(0, 0, targetImage.Width, targetImage.Height);
}
else
{
rectangle = Rectangle.Intersect(rectangle.Value,
new Rectangle(0, 0, targetImage.Width, targetImage.Height));
if (rectangle.Value.IsEmpty)
{
return;
}
}
using (Graphics graphics = Graphics.FromImage(targetImage))
{
Zoom(image, graphics, rectangle.Value, type);
}
}
///
/// 缩放(按比例)
///
///
///
///
///
public static void Zoom(Image image, Graphics graphics, Rectangle rectangle,
ZoomType type = ZoomType.Adaptive)
{
switch (type)
{
case ZoomType.WidthRatio:
ZoomWidth(image, graphics, rectangle);
break;
case ZoomType.HeightRatio:
ZoomHeight(image, graphics, rectangle);
break;
default:
decimal ratioHeight = rectangle.Height * 1m / image.Height;
decimal ratioWidth = rectangle.Width * 1m / image.Width;
if (ratioHeight != ratioWidth)
{
bool isWidth = ((ratioWidth > ratioHeight) == (type == ZoomType.Filled));
if (isWidth)
{
ZoomWidth(image, graphics, rectangle);
}
else
{
ZoomHeight(image, graphics, rectangle);
}
}
else
{
graphics.DrawImage(image, rectangle);
}
break;
}
}
#endregion
#region 剪裁
///
/// 剪裁
///
///
///
///
public static Image Cut(Image image, Rectangle rectangle)
{
Rectangle rectImage = new Rectangle(0, 0, image.Width, image.Height);
Rectangle rect = Rectangle.Intersect(rectangle, rectImage);
if (rect.IsEmpty)
{
return null;
}
//using (Bitmap tmp = new Bitmap(rectangle.Width, rectangle.Height))
Bitmap tmp = new Bitmap(rectangle.Width, rectangle.Height);
try
{
using (Graphics graphics = Graphics.FromImage(tmp))
{
SetGraphicsHighQuality(graphics);
graphics.DrawImage(image,
(rectangle.X < 0 ? -rectangle.X : 0),
(rectangle.Y < 0 ? -rectangle.Y : 0),
rect, GraphicsUnit.Pixel);
}
return tmp;
}
catch
{
tmp.Dispose();
throw;
}
}
#endregion
#region 显示
// 水平 左 中 右
// 垂直 上 中 下
///
/// 显示
///
///
///
///
///
///
public static Image Show(Image image, Size size,
ContentAlignment alignment = ContentAlignment.TopLeft, bool cut = true)
{
Image targetImage = new Bitmap(size.Width, size.Height);
Show(image, targetImage, null, alignment, cut);
return targetImage;
}
///
/// 显示
///
///
///
///
///
///
public static void Show(Image image, Image targetImage, Rectangle? rectangle = null,
ContentAlignment alignment = ContentAlignment.TopLeft, bool cut = true)
{
if (rectangle == null)
{
rectangle = new Rectangle(0, 0, targetImage.Width, targetImage.Height);
}
else
{
rectangle = Rectangle.Intersect(rectangle.Value,
new Rectangle(0, 0, targetImage.Width, targetImage.Height));
if (rectangle.Value.IsEmpty)
{
return;
}
}
using (Graphics graphics = Graphics.FromImage(targetImage))
{
Show(image, graphics, rectangle.Value, alignment, cut);
}
}
///
/// 显示
///
///
///
///
///
///
public static void Show(Image image, Graphics graphics, Rectangle rectangle,
ContentAlignment alignment = ContentAlignment.TopLeft, bool cut = true)
{
int x = 0;
int y = 0;
switch (alignment)
{
case ContentAlignment.TopLeft:
break;
case ContentAlignment.TopCenter:
x = (rectangle.Width - image.Width) / 2;
break;
case ContentAlignment.TopRight:
x = (rectangle.Width - image.Width);
break;
case ContentAlignment.MiddleLeft:
y = (rectangle.Height - image.Height) / 2;
break;
case ContentAlignment.MiddleCenter:
x = (rectangle.Width - image.Width) / 2;
y = (rectangle.Height - image.Height) / 2;
break;
case ContentAlignment.MiddleRight:
x = (rectangle.Width - image.Width);
y = (rectangle.Height - image.Height) / 2;
break;
case ContentAlignment.BottomLeft:
y = (rectangle.Height - image.Height);
break;
case ContentAlignment.BottomCenter:
x = (rectangle.Width - image.Width) / 2;
y = (rectangle.Height - image.Height);
break;
case ContentAlignment.BottomRight:
x = (rectangle.Width - image.Width);
y = (rectangle.Height - image.Height);
break;
default:
break;
}
Rectangle rectIamge = new Rectangle(0, 0, image.Width, image.Height);
if (cut)
{
Rectangle rect = new Rectangle(-x, -y, rectangle.Width, rectangle.Height);
rectIamge = Rectangle.Intersect(rectIamge, rect);
if (x > 0)
{
x += rectangle.X;
}
else
{
x = rectangle.X;
}
if (y > 0)
{
y += rectangle.Y;
}
else
{
y = rectangle.Y;
}
}
else
{
x += rectangle.X;
y += rectangle.Y;
}
SetGraphicsHighQuality(graphics);
graphics.DrawImage(image, x, y, rectIamge, GraphicsUnit.Pixel);
}
#endregion
#region 压缩
///
/// 压缩
///
///
///
///
///
public static Stream ZipImage(Image image, long quality, Size? size = null)
{
bool isZoom = true;
if (size == null)
{
isZoom = false;
size = image.Size;
}
Image bitmap = image;
if (isZoom)
{
using (Bitmap tmp = new Bitmap(size.Value.Width, size.Value.Height))
{
Stretch(image, tmp);
bitmap = tmp;
}
}
else
{
}
using (EncoderParameters myEncoderParameters = new EncoderParameters(1))
{
using (EncoderParameter myEncoderParameter = new EncoderParameter(Encoder.Quality, quality))
{
myEncoderParameters.Param[0] = myEncoderParameter;
ImageCodecInfo codecInfo = GetEncoderInfo(image.RawFormat.ToString());
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, codecInfo, myEncoderParameters);
return ms;
}
}
}
///
/// 获取图片编码信息
///
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders())
{
if (encoder.MimeType == mimeType)
{
return encoder;
}
}
return null;
}
#endregion
#region 设置透明
///
/// 设置透明
///
///
public static void MakeTransparent(Graphics graphics)
{
graphics.Clear(Color.Transparent);
}
///
/// 设置透明
///
///
public static void MakeTransparent(Bitmap image)
{
image.MakeTransparent();
}
///
/// Returns a transparent background GIF image from the specified Bitmap.
///
/// The Bitmap to make transparent.
/// The Color to make transparent.
/// New Bitmap containing a transparent background gif.
public static Bitmap MakeTransparentGif(Bitmap bitmap, Color color)
{
byte R = color.R;
byte G = color.G;
byte B = color.B;
using (MemoryStream fin = new MemoryStream())
{
bitmap.Save(fin, ImageFormat.Gif);
using (MemoryStream fout = new MemoryStream((int)fin.Length))
{
byte[] buf = new byte[256];
byte transparentIdx = 0;
fin.Seek(0, SeekOrigin.Begin);
//header
int count = fin.Read(buf, 0, 13);
if ((buf[0] != 71) || (buf[1] != 73) || (buf[2] != 70))
{
return null; //GIF
}
fout.Write(buf, 0, 13);
int i = 0;
if ((buf[10] & 0x80) > 0)
{
i = 1 << ((buf[10] & 7) + 1) == 256 ? 256 : 0;
}
for (; i != 0; i--)
{
fin.Read(buf, 0, 3);
if ((buf[0] == R) && (buf[1] == G) && (buf[2] == B))
{
transparentIdx = (byte)(256 - i);
}
fout.Write(buf, 0, 3);
}
while (true)
{
fin.Read(buf, 0, 1);
fout.Write(buf, 0, 1);
if (buf[0] != 0x21)
{
break;
}
fin.Read(buf, 0, 1);
fout.Write(buf, 0, 1);
bool gcePresent = (buf[0] == 0xf9);
while (true)
{
fin.Read(buf, 0, 1);
fout.Write(buf, 0, 1);
if (buf[0] == 0)
{
break;
}
count = buf[0];
if (fin.Read(buf, 0, count) != count)
{
return null;
}
if (gcePresent)
{
if (count == 4)
{
buf[0] |= 0x01;
buf[3] = transparentIdx;
}
}
fout.Write(buf, 0, count);
}
}
while (count > 0)
{
count = fin.Read(buf, 0, 1);
fout.Write(buf, 0, 1);
}
fin.Close();
fout.Flush();
return new Bitmap(fout);
}
}
}
#endregion
///
/// 按像素放大整数倍
///
///
///
///
///
public static Bitmap ZoomPixel(Bitmap image, int ratioWidth, int ratioHeight)
{
if (image == null || ratioWidth < 1 || ratioHeight < 1)
{
return image;
}
Bitmap targetImage = new Bitmap(image.Width * ratioWidth, image.Height * ratioHeight);
BitmapData targetImageData = null;
try
{
BitmapData imageData =
image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
targetImageData =
targetImage.LockBits(new Rectangle(0, 0, targetImage.Width, targetImage.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
byte[] imagePixels = new byte[imageData.Stride * imageData.Height];
Marshal.Copy(imageData.Scan0, imagePixels, 0, imagePixels.Length);
byte[] targetImagePixels = new byte[targetImageData.Stride * targetImageData.Height];
int targetImageIndex = 0;
for (int y = 0; y < image.Height; y++)
{
for (int rh = 0; rh < ratioHeight; rh++)
{
for (int x = 0; x < image.Width; x++)
{
for (int rw = 0; rw < ratioWidth; rw++)
{
int i = y * imageData.Stride + x * 4;
targetImagePixels[targetImageIndex++] = imagePixels[i++];
targetImagePixels[targetImageIndex++] = imagePixels[i++];
targetImagePixels[targetImageIndex++] = imagePixels[i++];
targetImagePixels[targetImageIndex++] = imagePixels[i++];
}
}
}
}
Marshal.Copy(targetImagePixels, 0, targetImageData.Scan0, targetImagePixels.Length);
}
finally
{
targetImage.UnlockBits(targetImageData);
}
return targetImage;
}
/*
// 对于GDI+,在正常的操作,Bitmap,Graphcis,DrawImage或者DrawString ,生成图片的话,会产生很多杂点,或者是图片质量不稳定..尤其是在读取图片后,生成缩略图之后,文件会被压缩而失真..
//主要原因是因为没有重新设置Graphics的几个属性..
//1.Graphics.SmoothingMode属性: 例如SmoothingMode.HighQuality可以产生高质量图片,但是效率低.
//2.Graphics.CompositingQuality 属性: 例如:CompositingQuality.HighQuality也是产生高质量图,效率低下.
//3.Graphics.InterpolationMode 属性, 例如:InterpolationMode.HighQualityBicubic与前两个也是同样的效果.
// 这三个属性的值都是Enum,具体的Enum参数可以查看MSDN的说明,在这里就我不多说了,
//如果是对图片进行放大,缩小,可以调整Graphics.CompositingQuality 和Graphics.InterpolationMode 两个属性,如果是图片生成, 则可以调整Graphics.SmoothingMode属性
//另外一个问题就是关于文字生成的..按照正常的模式生成的文字, 可以很明显的看到文字带有锯齿..解决的办法也是需要修改Graphics的一个属性: Graphics.TextRenderingHint注意一点, 修改TextRenderingHint的话, 需要引入System.Drawing.Text, 例如:Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
// 经过对这四个属性的修改,操作大部分的图片之后,产生的结果都是比较让人满意
*/
///
///
///
///
public static void SetGraphicsHighQuality(Graphics graphics)
{
// 设置绘图质量
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingMode = CompositingMode.SourceOver;
//graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
}
}
}