发布:2022/12/27 11:05:45作者:管理员 来源:本站 浏览次数:611
背景:
从网上下了几十个gif图片,准备用来做学习用,但是这图片里面水印比较多,就想到了能不能通过代码处理一下这个水印。
方案:
首先想到的是将gif的每一帧的图片都解出来,单个单个处理图片,单个图片水印处理完成之后再重新生成回gif图片。
到此,方案有了,相当于需求分析已经做完,就差编码了,废话不多说,进入主题。
第一步:
先把所有的gif的每一帧解出来
Image gif = Image.FromFile(@"c:\users\server\desktop\91c9.gif");
FrameDimension fd = new FrameDimension(gif.FrameDimensionsList[0]);
//获取帧数(gif图片可能包含多帧,其它格式图片一般仅一帧)
int count = gif.GetFrameCount(fd);
//以jpeg格式保存各帧
for (int i = 0; i < count; i++)
{
gif.SelectActiveFrame(fd, i);
var savePath = @"C:\Users\Server\Desktop\gif\frame_" + i + ".jpg";
gif.Save(savePath , ImageFormat.Jpeg);
}
至此,图片已经完全解出来了,打开图片看,好在这个图片的水印都在四个角的位置(一般也不至于将水印写在中间部分,那样极大印象了gif图片的整体效果),利用截图工具先计算需要去掉水印框的矩形框大小,然后利用FillRectangle方法将该处填充为与图片同背景色的颜色区块。
第二步:填充选择区块
FrameDimension fd = new FrameDimension(gif.FrameDimensionsList[0]);
//获取帧数(gif图片可能包含多帧,其它格式图片一般仅一帧)
int count = gif.GetFrameCount(fd);
//以jpeg格式保存各帧
for (int i = 0; i < count; i++)
{
gif.SelectActiveFrame(fd, i);
System.IO.MemoryStream stream = new System.IO.MemoryStream();
gif.Save(stream, ImageFormat.Jpeg);
//由于导出的帧图片较多,直接存入到流,避免频繁的IO
Bitmap bg_bitmap = new Bitmap(stream);
using (Graphics g = Graphics.FromImage(bg_bitmap))
{
var bitmapW = bg_bitmap.Width;
var bitmapH = bg_bitmap.Height;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
//左上角的某个位置
var point = new System.Drawing.Point(0, 0);//位置
var brush = new SolidBrush(Color.FromArgb(232, 232, 232));
var size = new System.Drawing.Size(33, 46);//大小
var racent = new Rectangle(point, size);
g.FillRectangle(brush, racent);
//右下角的位置
point = new System.Drawing.Point(bitmapW - 69, bitmapH - 22);//位置
size = new System.Drawing.Size(69, 22);//大小
racent = new Rectangle(point, size);
g.FillRectangle(brush, racent);
EncoderParameter p;
EncoderParameters ps;
ps = new EncoderParameters(1);
p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
ps.Param[0] = p;
ImageCodecInfo ii = GetCodecInfo("image/jpeg");
var savePath = @"C:\Users\Server\Desktop\gif\frame_" + i + "_b.jpg";
bg_bitmap.Save(savePath, ii, ps);//保存图片
}
}
补充获取图片格式的方法:
ImageCodecInfo GetCodecInfo(string mimeType)
{
ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo ici in CodecInfo)
{
if (ici.MimeType == mimeType) return ici;
}
return null;
}
第三步:将去掉水印的图片重新组合成gif
GifBitmapEncoder gEnc = new GifBitmapEncoder();
for (int i = 0; i < count; i++)
{
var frameFilePath = @"C:\Users\Server\Desktop\gif\frame_" + i + "_b.jpg";
var img = System.Drawing.Image.FromFile(frameFilePath);
System.Drawing.Bitmap bmpImage = (Bitmap)img;
var bmp = bmpImage.GetHbitmap();
var src = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
gEnc.Frames.Add(BitmapFrame.Create(src));
}
using (FileStream fs = new FileStream(@"C:\Users\Server\Desktop\test.gif", FileMode.Create))
{
gEnc.Save(fs);
}
注意:此处需要引入
using System.Windows;
using System.Windows.Media.Imaging;
这两个命名空间,到这里,已经处理完成了。
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4