快速读取图像文件的高度和宽度
using PresentationCore;
using System.Windows.Media;
/// <summary>
/// 快速读取图像文件的高度和宽度
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string GetImageSize(string fileName)
{
try
{
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var frame = System.Windows.Media.Imaging.BitmapFrame.Create(stream, System.Windows.Media.Imaging.BitmapCreateOptions.DelayCreation, System.Windows.Media.Imaging.BitmapCacheOption.None);
var width = frame.PixelWidth;
var height = frame.PixelHeight;
return $"{width}*{height}";
}
}
catch (Exception ex)
{
Console.WriteLine("图片格式异常:" + ex.Message);
return string.Empty;
}
}
图片生成指定质量的流
/// <summary>
/// 图片生成指定质量的流
/// </summary>
/// <param name="encoder">图片编码</param>
/// <param name="quality">图片质量</param>
/// <returns></returns>
public Stream ToStream(ImageCodecInfo encoder, int quality)
{
var myEncoder = Encoder.Quality;
var myEncoderParameters = new EncoderParameters(1);
var myEncoderParam = new EncoderParameter(myEncoder, quality);
myEncoderParameters.Param[0] = myEncoderParam;
var rslt = new MemoryStream();
_bitmap.Save(rslt, encoder, myEncoderParameters);
return rslt;
}
图片一般帮助类
/// <summary>
/// 图片一般帮助类
/// </summary>
public partial class ImageHelper : IDisposable
{
readonly string _fileName;
Bitmap _bitmap;
/// <summary>
/// 图片所指位图
/// </summary>
public Bitmap SourceBitmap
{
get { return _bitmap; }
}
public ImageHelper(string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException(fileName, "fileName is NULL!");
}
if (!File.Exists(fileName))
{
throw new NotImplementedException("the image is not exist!!");
}
_fileName = fileName;
_bitmap = new Bitmap(fileName);
}
public ImageHelper(Image img)
{
_bitmap = (Bitmap)img;
_fileName = string.Empty;
}
public ImageHelper(Stream stream)
{
_bitmap = (Bitmap)Image.FromStream(stream);
_fileName = string.Empty;
}
public byte[] ToBytes(string extension)
{
return ToBytes(GetFormat(extension));
}
public byte[] ToBytes(ImageFormat imageFormat)
{
using var ms = new MemoryStream();
_bitmap.Save(ms, imageFormat);
return ms.ToArray();
}
public void DrawRectangles(Color color, RectangleF[] rects)
{
if (rects == null)
{
return;
}
var pen = new Pen(color, 5);
using Graphics g = Graphics.FromImage(_bitmap);
g.DrawRectangles(pen, rects);
}
public void DrawRectangle(Color color, Rectangle rect)
{
var pen = new Pen(color, 5);
using Graphics g = Graphics.FromImage(_bitmap);
g.DrawRectangle(pen, rect);
}
public Color StringToColor(string colorName)
{
if (colorName.StartsWith("#"))
{
colorName = colorName.Replace("#", string.Empty);
}
if (int.TryParse(colorName, System.Globalization.NumberStyles.HexNumber, null, out int value))
{
return Color.FromArgb(
//Convert.ToByte((value >> 24) & 255), // a
Convert.ToByte((value >> 16) & 255), // R
Convert.ToByte((value >> 8) & 255), // G
Convert.ToByte((value >> 0) & 255) // B
);
}
return Color.Red;
}
/// <summary>
/// 取文件名后缀(小写)
/// </summary>
/// <param name="name">文件名</param>
/// <returns>返回小写后缀,不带“.”</returns>
public string GetFileExt(string name)
{
return name.Split('.').Last().ToLower();
}
#region Dispose
// 是否释放
private bool _isDisposed = false;
// 锁对象
private static readonly object _clockObj = new object();
~ImageHelper()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// 释放相关资源
protected virtual void Dispose(bool disposing)
{
//不需要多次释放
if (_isDisposed) return;
//由于Dispose方法可能被多线程调用,所以加锁以确保线程安全
lock (_clockObj)
{
if (disposing)
{
if (!string.IsNullOrWhiteSpace(_fileName) && File.Exists(_fileName))
{
File.Delete(_fileName);
}
}
if (_bitmap != null)
{
_bitmap.Dispose();
_bitmap = null;
}
_isDisposed = true;
}
}
#endregion
}
图片缩略
/// <summary>
/// 图片伸缩(百分比)
/// </summary>
/// <param name="stretchWidth">伸缩的宽度(%)</param>
/// <param name="stretchHeight">伸缩的高度(%)</param>
public void StretchImage(int stretchWidth, int stretchHeight)
{
if (stretchHeight == _bitmap.Height && stretchWidth == _bitmap.Width)
{
return;
}
int width = _bitmap.Width;
int height = _bitmap.Height;
Bitmap bitmap = new Bitmap(width * stretchWidth / 100, height * stretchHeight / 100);
Graphics gSave = Graphics.FromImage(bitmap);
Point[] p = new Point[3];
p[0].X = 0;
p[1].X = width * stretchWidth / 100;
p[2].X = 0;
p[0].Y = 0;
p[1].Y = 0;
p[2].Y = height * stretchHeight / 100;
gSave.Clear(Color.White);
gSave.DrawImage(_bitmap, p);
gSave.Dispose();
_bitmap.Dispose();
_bitmap = bitmap;
}
/// <summary>
/// 图片缩略(像素)
/// </summary>
/// <param name="thumbWidth">伸缩的宽度(像素)</param>
/// <param name="thumbHeight">伸缩的高度(像素)</param>
public void ThumbImage(int thumbWidth, int thumbHeight)
{
if (thumbHeight == _bitmap.Height && thumbWidth == _bitmap.Width)
{
return;
}
Bitmap bitmap = new Bitmap(thumbWidth, thumbHeight);
Graphics gSave = Graphics.FromImage(bitmap);
Point[] p = new Point[3];
p[0].X = 0;
p[1].X = thumbWidth;
p[2].X = 0;
p[0].Y = 0;
p[1].Y = 0;
p[2].Y = thumbHeight;
gSave.Clear(Color.White);
gSave.DrawImage(_bitmap, p);
gSave.Dispose();
_bitmap.Dispose();
_bitmap = bitmap;
}
调整图片质量
/// <summary>
/// 调整图片质量
/// </summary>
/// <param name="encoder">图片编码</param>
/// <param name="quality">图片质量</param>
/// <returns></returns>
public void QualityImage(ImageCodecInfo encoder, int quality)
{
var myEncoder = Encoder.Quality;
var myEncoderParameters = new EncoderParameters(1);
var myEncoderParam = new EncoderParameter(myEncoder, quality);
myEncoderParameters.Param[0] = myEncoderParam;
var stream = new MemoryStream();
_bitmap.Save(stream, encoder, myEncoderParameters);
var bitmap = (Bitmap)Image.FromStream(stream);
_bitmap.Dispose();
_bitmap = bitmap;
}
图片转换
/// <summary>
/// 图片转换(后拉伸)
/// </summary>
/// <param name="rotateAngle">旋转度数</param>
/// <param name="stretchWidth">水平伸缩</param>
/// <param name="stretchHeight">竖直伸缩</param>
/// <param name="tiltWidth">水平倾斜</param>
/// <param name="tiltHeight">竖直倾斜</param>
/// <returns></returns>
public void DistortImage1(int rotateAngle, int stretchWidth, int stretchHeight, int tiltWidth, int tiltHeight)
{
TiltWidthImage(tiltWidth);
TiltHeightImage(tiltHeight);
RotateAngle(rotateAngle);
StretchImage(stretchWidth, stretchHeight);
}
/// <summary>
/// 图片转换(先缩小)
/// </summary>
/// <param name="rotateAngle">旋转度数</param>
/// <param name="stretchWidth">水平伸缩</param>
/// <param name="stretchHeight">竖直伸缩</param>
/// <param name="tiltWidth">水平倾斜</param>
/// <param name="tiltHeight">竖直倾斜</param>
/// <returns></returns>
public void DistortImage2(int rotateAngle, int stretchWidth, int stretchHeight, int tiltWidth, int tiltHeight)
{
StretchImage(stretchWidth, stretchHeight);
TiltWidthImage(tiltWidth);
TiltHeightImage(tiltHeight);
RotateAngle(rotateAngle);
}
/// <summary>
/// 图片水平倾斜
/// </summary>
/// <param name="tiltWidth">水平偏移长度</param>
public void TiltWidthImage(int tiltWidth)
{
if (tiltWidth == 0)
{
return;
}
int width = _bitmap.Width;
int height = _bitmap.Height;
Bitmap bitmap = new Bitmap(width + Math.Abs(tiltWidth), height);
Graphics gSave = Graphics.FromImage(bitmap);
Point[] p = new Point[3];
if (tiltWidth > 0)
{
p[0].X = Math.Abs(tiltWidth);
p[1].X = width + Math.Abs(tiltWidth);
p[2].X = 0;
}
else
{
p[0].X = 0;
p[1].X = _bitmap.Width;
p[2].X = Math.Abs(tiltWidth);
}
p[0].Y = 0;
p[1].Y = 0;
p[2].Y = height;
gSave.Clear(Color.White);
gSave.DrawImage(_bitmap, p);
gSave.Dispose();
_bitmap.Dispose();
_bitmap = bitmap;
}
/// <summary>
/// 图片竖直倾斜
/// </summary>
/// <param name="tiltHeight">竖直偏移长度</param>
public void TiltHeightImage(int tiltHeight)
{
if (tiltHeight == 0)
{
return;
}
int width = _bitmap.Width;
int height = _bitmap.Height;
Bitmap bitmap = new Bitmap(width, height + Math.Abs(tiltHeight));
Graphics gSave = Graphics.FromImage(bitmap);
Point[] p = new Point[3];
p[0].X = 0;
p[1].X = width;
p[2].X = 0;
if (tiltHeight > 0)
{
p[0].Y = Math.Abs(tiltHeight);
p[1].Y = 0;
p[2].Y = height + Math.Abs(tiltHeight);
}
else
{
p[0].Y = 0;
p[1].Y = Math.Abs(tiltHeight);
p[2].Y = height;
}
gSave.Clear(Color.White);
gSave.DrawImage(_bitmap, p);
gSave.Dispose();
_bitmap.Dispose();
_bitmap = bitmap;
}
图片裁切
/// <summary>
/// 图片裁切
/// </summary>
/// <param name="StartX">开始坐标X</param>
/// <param name="StartY">开始坐标Y</param>
/// <param name="iWidth">宽度</param>
/// <param name="iHeight">高度</param>
/// <returns>剪裁后的Bitmap</returns>
public void CutImg(int StartX, int StartY, int iWidth, int iHeight)
{
if (_bitmap == null) return;
if (iWidth == 0 || iHeight == 0) return;
int w = _bitmap.Width;
int h = _bitmap.Height;
if (StartX >= w || StartY >= h) return;
if (StartX + iWidth > w) { iWidth = w - StartX; }
if (StartY + iHeight > h) { iHeight = h - StartY; }
Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bmpOut))
{
g.DrawImage(_bitmap, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
}
_bitmap.Dispose();
_bitmap = bmpOut;
}
图片旋转
/// <summary>
/// 图片旋转
/// </summary>
/// <param name="angle">旋转度数</param>
public void RotateAngle(int angle)
{
angle = angle % 360;
if (angle == 0)
{
return;
}
//原图的宽和高
int srcWidth = _bitmap.Width;
int srcHeight = _bitmap.Height;
//图像旋转之后所占区域宽和高
Rectangle rotateRec = GetRotateRectangle(srcWidth, srcHeight, angle);
int rotateWidth = rotateRec.Width;
int rotateHeight = rotateRec.Height;
//目标位图
Bitmap destImage = null;
Graphics graphics = null;
try
{
//定义画布,宽高为图像旋转后的宽高
destImage = new Bitmap(rotateWidth, rotateHeight);
//graphics根据destImage创建,因此其原点此时在destImage左上角
graphics = Graphics.FromImage(destImage);
//要让graphics围绕某矩形中心点旋转N度,分三步
//第一步,将graphics坐标原点移到矩形中心点,假设其中点坐标(x,y)
//第二步,graphics旋转相应的角度(沿当前原点)
//第三步,移回(-x,-y)
//获取画布中心点
Point centerPoint = new Point(rotateWidth / 2, rotateHeight / 2);
//将graphics坐标原点移到中心点
graphics.TranslateTransform(centerPoint.X, centerPoint.Y);
//graphics旋转相应的角度(绕当前原点)
graphics.RotateTransform(angle);
//恢复graphics在水平和垂直方向的平移(沿当前原点)
graphics.TranslateTransform(-centerPoint.X, -centerPoint.Y);
//此时已经完成了graphics的旋转
graphics.Clear(Color.White);
//计算:如果要将源图像画到画布上且中心与画布中心重合,需要的偏移量
Point Offset = new Point((rotateWidth - srcWidth) / 2, (rotateHeight - srcHeight) / 2);
//将源图片画到rect里(rotateRec的中心)
graphics.DrawImage(_bitmap, new Rectangle(Offset.X, Offset.Y, srcWidth, srcHeight));
//重至绘图的所有变换
graphics.ResetTransform();
graphics.Save();
}
catch (Exception ex)
{
string err = ex.Message;
}
finally
{
if (graphics != null)
graphics.Dispose();
}
_bitmap.Dispose();
_bitmap = destImage;
}
private Rectangle GetRotateRectangle(int width, int height, float angle)
{
double radian = angle * Math.PI / 180; ;
double cos = Math.Cos(radian);
double sin = Math.Sin(radian);
//只需要考虑到第四象限和第三象限的情况取大值(中间用绝对值就可以包括第一和第二象限)
int newWidth = (int)(Math.Max(Math.Abs(width * cos - height * sin), Math.Abs(width * cos + height * sin)));
int newHeight = (int)(Math.Max(Math.Abs(width * sin - height * cos), Math.Abs(width * sin + height * cos)));
return new Rectangle(0, 0, newWidth, newHeight);
}
得到图片格式
/// <summary>
/// 得到图片格式
/// </summary>
/// <param name="name">文件名称</param>
/// <returns>ImageFormat</returns>
public ImageFormat GetFormat(string name)
{
string ext = GetFileExt(name);
switch (ext)
{
case "ico":
return ImageFormat.Icon;
case "bmp":
return ImageFormat.Bmp;
case "png":
return ImageFormat.Png;
case "gif":
return ImageFormat.Gif;
default:
return ImageFormat.Jpeg;
}
}
获取图片编码信息
/// <summary>
/// 获取图片编码信息
/// </summary>
/// <param name="imageFormat">图片格式</param>
/// <returns></returns>
public ImageCodecInfo GetEncoder(ImageFormat imageFormat)
{
var codecs = ImageCodecInfo.GetImageEncoders();
foreach (var item in codecs)
{
if (item.FormatID == imageFormat.Guid)
{
return item;
}
}
return null;
}
图片新尺寸调整
/// <summary>
/// 计算新尺寸(保持纵横比)
/// </summary>
/// <param name="srcWidth">原始宽度</param>
/// <param name="srcHeight">原始高度</param>
/// <param name="dstWidth">目标宽度</param>
/// <param name="dstHeight">目标高度</param>
/// <returns></returns>
public Size ResizeImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
{
if (dstWidth <= 0)
dstWidth = srcWidth;
if (dstHeight <= 0)
dstHeight = srcHeight;
decimal MAX_WIDTH = dstWidth;
decimal MAX_HEIGHT = dstHeight;
decimal ASPECT_RATIO = MAX_WIDTH / MAX_HEIGHT;
int newWidth, newHeight;
decimal originalWidth = srcWidth;
decimal originalHeight = srcHeight;
if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT)
{
decimal factor;
if (originalWidth / originalHeight > ASPECT_RATIO)
{
factor = originalWidth / MAX_WIDTH;
newWidth = Convert.ToInt32(originalWidth / factor);
newHeight = Convert.ToInt32(originalHeight / factor);
}
else
{
factor = originalHeight / MAX_HEIGHT;
newWidth = Convert.ToInt32(originalWidth / factor);
newHeight = Convert.ToInt32(originalHeight / factor);
}
}
else
{
newWidth = srcWidth;
newHeight = srcHeight;
}
return new Size(newWidth, newHeight);
}
图片保存
/// <summary>
/// BitmapImage保存为png
/// </summary>
/// <param name="bitmapImage">BitmapImage</param>
/// <param name="filePath">保存绝对路径</param>
private void SaveBitmapIamge(BitmapImage bitmapImage, string filePath)
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
encoder.Save(fs);
}
}