C#常用的图片处理方法-图片剪切、图片压缩、多图合并代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/// <summary>
/// 图片转成圆角方法二
/// </summary>
private Bitmap WayTwo(Bitmap bitmap)
{
    //using (Image i = new Bitmap(file))
    using (Image i = bitmap)
    {
        Bitmap b = new Bitmap(i.Width, i.Height);
        using (Graphics g = Graphics.FromImage(b))
        {
            g.DrawImage(i, 0, 0, b.Width, b.Height);
            int r = Math.Min(b.Width, b.Height) / 2;
            PointF c = new PointF(b.Width / 2.0F, b.Height / 2.0F);
            for (int h = 0; h < b.Height; h++)
                for (int w = 0; w < b.Width; w++)
                    if ((int)Math.Pow(r, 2) < ((int)Math.Pow(w * 1.0 - c.X, 2) + (int)Math.Pow(h * 1.0 - c.Y, 2)))
                    {
                        b.SetPixel(w, h, Color.Transparent);
                    }
        }
        return b;
    }
}
 
/// <summary> 
/// 合并图片 
/// </summary> 
/// <param name="imgBack"></param> 
/// <param name="img"></param> 
/// <returns></returns> 
public static Bitmap CombinImage(Image imgBack, Image img, int xDeviation = 0, int yDeviation = 0)
{
    Bitmap bmp = new Bitmap(imgBack.Width, imgBack.Height);
    Graphics g = Graphics.FromImage(bmp);
 
    g.DrawImage(imgBack, 0, 0, imgBack.Width, imgBack.Height);
    //白色边框
    // g.FillRectangle(System.Drawing.Brushes.White, imgBack.Width / 2 - img.Width / 2 + xDeviation - 1, imgBack.Height / 2 - img.Height / 2 + yDeviation - 1, img.Width + 2, img.Height + 2);
    //填充图片
 
    //设置高质量插值法
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //设置高质量,低速度呈现平滑程度
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.CompositingQuality = CompositingQuality.HighQuality;
 
    g.Clear(Color.Transparent);
 
    //防止出现渐变
    var imgAtt = new ImageAttributes();
    imgAtt.SetWrapMode(WrapMode.TileFlipXY);
 
    var x = imgBack.Width / 2 - img.Width / 2 + xDeviation;
    var y = imgBack.Height / 2 - img.Height / 2 + yDeviation;
    var width = img.Width;
    var height = img.Height;
    // g.DrawImage(img, imgBack.Width / 2 - img.Width / 2 + xDeviation, imgBack.Height / 2 - img.Height / 2 + yDeviation,img.Width , img.Height);
    g.DrawImage(img, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel, imgAtt);
 
    GC.Collect();
    return bmp;
}
 
/// <summary>
/// 从大图中截取一部分图片
/// </summary>
/// <param name="fromImage">来源图片</param>       
/// <param name="offsetX">从偏移X坐标位置开始截取</param>
/// <param name="offsetY">从偏移Y坐标位置开始截取</param>
/// <param name="width">保存图片的宽度</param>
/// <param name="height">保存图片的高度</param>
/// <returns></returns>
public Image ResizeImage(Image fromImage, int offsetX, int offsetY, int width, int height)
{
    //创建新图位图
    Bitmap bitmap = new Bitmap(width, height);
    //创建作图区域
    Graphics graphic = Graphics.FromImage(bitmap);
    //截取原图相应区域写入作图区
    graphic.DrawImage(fromImage, 0, 0, new Rectangle(offsetX, offsetY, width, height), GraphicsUnit.Pixel);
    //从作图区生成新图
    Image saveImage = Image.FromHbitmap(bitmap.GetHbitmap());
    ////保存图片
    //saveImage.Save(toImagePath, ImageFormat.Png);
    ////释放资源  
    //saveImage.Dispose();
    //graphic.Dispose();
    //bitmap.Dispose();
    return saveImage;
}
 
/// <summary>
/// 按照指定大小缩放图片,但是为了保证图片宽高比自动截取
/// </summary>
/// <param name="srcPath">原图片路径</param>
/// <param name="destWidth">目标图片宽</param>
/// <param name="destHeight">目标图片高</param>
/// <returns></returns>
public static Bitmap SizeImageWithOldPercent(Bitmap srcPath, int destWidth, int destHeight)
{
    Image srcImage = srcPath;
    try
    {
        // 要截取图片的宽度(原始宽度)
        int srcWidth = srcImage.Width;
        // 要截取图片的高度(原始高度)
        int srcHeight = srcImage.Height;
        // 截取开始横坐标
        int newX = 0;
        // 截取开始纵坐标
        int newY = 0;
 
        // 截取比例
        double whPercent = ((double)destWidth / (double)destHeight) * ((double)srcImage.Height / (double)srcImage.Width);
        if (whPercent > 1)
        {
            // 当前图片宽度对于要截取比例过大时
            srcWidth = int.Parse(Math.Round(srcImage.Width / whPercent).ToString());
        }
        else if (whPercent < 1)
        {
            // 当前图片高度对于要截取比例过大时
            srcHeight = int.Parse(Math.Round(srcImage.Height * whPercent).ToString());
        }
 
        if (srcWidth != srcImage.Width)
        {
            // 宽度有变化时,调整开始截取的横坐标
            newX = Math.Abs(int.Parse(Math.Round(((double)srcImage.Width - srcWidth) / 2).ToString()));
        }
        else if (srcHeight == srcImage.Height)
        {
            // 高度有变化时,调整开始截取的纵坐标
            newY = Math.Abs(int.Parse(Math.Round(((double)srcImage.Height - (double)srcHeight) / 2).ToString()));
        }
 
        // 将原始图片画到目标画布上,返回目标图片
        Bitmap cutedImage = CutImage(srcImage, newX, newY, srcWidth, srcHeight);
 
        // 在创建一个新的画布
        Bitmap bmp = new Bitmap(destWidth, destHeight);
        Graphics g = Graphics.FromImage(bmp);
 
        //设置高质量插值法
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        //设置高质量,低速度呈现平滑程度
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.Clear(Color.Transparent);
 
        //防止出现渐变
        var imgAtt = new ImageAttributes();
        imgAtt.SetWrapMode(WrapMode.TileFlipXY);
 
        // g.DrawImage(cutedImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, cutedImage.Width, cutedImage.Height), GraphicsUnit.Pixel);
        // 在画板的指定位置画图
        g.DrawImage(cutedImage, new Rectangle(0, 0, destWidth, destHeight), 0, 0, cutedImage.Width, cutedImage.Height, GraphicsUnit.Pixel, imgAtt);
        // g.Dispose();
 
        return bmp;
    }
    catch (Exception)
    {
        return null;
    }
}
 
 
/// <summary>
/// 剪裁 -- 用GDI+
/// </summary>
/// <param name="image">原始图片</param>
/// <param name="StartX">开始坐标X</param>
/// <param name="StartY">开始坐标Y</param>
/// <param name="destWidth">目标图片宽度</param>
/// <param name="destHeight">目标图片高度高度</param>
/// <returns>剪裁后的Bitmap</returns>
public static Bitmap CutImage(Image image, int StartX, int StartY, int destWidth, int destHeight)
{
    int srcWidth = image.Width;
    int srcHeight = image.Height;
    if (StartX >= srcWidth || StartY >= srcHeight)
    {
        // 开始截取坐标过大时,结束处理
        return null;
    }
 
    if (StartX + destWidth > srcWidth)
    {
        // 宽度过大时只截取到最大大小
        destWidth = srcWidth - StartX;
    }
 
    if (StartY + destHeight > srcHeight)
    {
        // 高度过大时只截取到最大大小
        destHeight = srcHeight - StartY;
    }
 
    try
    {
        // 根据目标图片的大小,实例化一个画布
        Bitmap bmpOut = new Bitmap(destWidth, destHeight);
        // 实例化一个画笔
        Graphics g = Graphics.FromImage(bmpOut);
 
        //设置高质量插值法
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        //设置高质量,低速度呈现平滑程度
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.Clear(Color.Transparent);
 
        // 将原始图片画到目标画布上
        // g.DrawImage(image,new Rectangle(0, 0, destWidth, destHeight), new Rectangle(StartX, StartY, destWidth, destHeight), GraphicsUnit.Pixel);
 
        //防止出现渐变(生成高质量不模糊的图片)
        var imgAtt = new ImageAttributes();
        imgAtt.SetWrapMode(WrapMode.TileFlipXY);
        // 在画板的指定位置画图
        g.DrawImage(image, new Rectangle(0, 0, destWidth, destHeight), StartX, StartY, destWidth, destHeight, GraphicsUnit.Pixel, imgAtt);
 
        g.Dispose();
 
        return bmpOut;
    }
    catch
    {
        return null;
    }
 
}
public static Bitmap GetThumbnail(Bitmap b, int destHeight, int destWidth)
{
    System.Drawing.Image imgSource = b;
    System.Drawing.Imaging.ImageFormat thisFormat = imgSource.RawFormat;
    int sW = 0, sH = 0;
    // 按比例缩放          
    int sWidth = imgSource.Width;
    int sHeight = imgSource.Height;
    if (sHeight > destHeight || sWidth > destWidth)
    {
        if ((sWidth * destHeight) > (sHeight * destWidth))
        {
            sW = destWidth;
            sH = (destWidth * sHeight) / sWidth;
        }
        else
        {
            sH = destHeight;
            sW = (sWidth * destHeight) / sHeight;
        }
    }
    else
    {
        return b;
        //sW = sWidth;
        //sH = sHeight;
    }
 
    Bitmap outBmp = new Bitmap(destWidth, destHeight);
    Graphics g = Graphics.FromImage(outBmp);
    //设置高质量插值法
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //设置高质量,低速度呈现平滑程度
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.CompositingQuality = CompositingQuality.HighQuality;
 
    g.Clear(Color.Transparent);
 
    //防止出现渐变
    var imgAtt = new ImageAttributes();
    imgAtt.SetWrapMode(WrapMode.TileFlipXY);
    //在画板的指定位置画图
    g.DrawImage(imgSource, new Rectangle((destWidth - sW) / 2, (destHeight - sH) / 2, sW, sH), 0, 0,
        imgSource.Width, imgSource.Height, GraphicsUnit.Pixel, imgAtt);
 
    g.Dispose();
    // 以下代码为保存图片时,设置压缩质量    
    //EncoderParameters encoderParams = new EncoderParameters();
    //long[] quality = new long[1];
    //quality[0] = 100;
    //EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
    //encoderParams.Param[0] = encoderParam;
 
    imgSource.Dispose();
    return outBmp;
}

  

以下是图片处理常用的一些方法;

 

posted @   星辰与大海  阅读(1191)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· Qt个人项目总结 —— MySQL数据库查询与断言
点击右上角即可分享
微信分享提示