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; } } }