C# gif添加水印

来源:互联网 发布:淘宝怎么看店铺收藏 编辑:程序博客网 时间:2024/05/16 01:45

想做个gif添加水印的东西

然后上网查各种资料

先是看了这位大神的:

http://www.cnblogs.com/livexy/archive/2010/07/05/1771714.html

上面直接就有  心中窃喜...哇没想到这么简单..

不过把code弄下来之后发现gif貌似不管用啊....其他jpg png我就没去试了..

后面又找了很多资料 找资料的过程中 慢慢换了思路 gif可以分解成很多张 jpg (也就是帧数)

我只需要把每一帧都加上水印 然后在 合并起来就可以了  谁知道想得倒是很简单啊 实行起来真特么难啊 找不到资料啊

连第一步都搞不定了...

直到找到了这个文章: http://blog.sina.com.cn/s/blog_4c6e822d0102dzin.html

现在 gif可以 拆分成很多帧数的图片了 保存起来也没有什么问题(我用某看图王看gif的时候 发现是231帧数 用这个code处理之后保存的图片也是231帧)

ok现在全部可以保存成jpg了吧  jpg加水印很简单 百度搜索一下即可!其实就跟平时做的验证码差不多..

ok 那现在就开始找 将jpg合成保存成gif的代码

然后发现 博客里面说的都需要一个 dll   Gif.Components.dll   然后借助于这个类 AnimatedGifEncoder 来实现 不知道百度一下 肯定有很多博客的.看看就好了

这里要鄙视一些博客搬运工,你特么的抄袭人家的东西 自己从来都没有跑过?直接拿过去就粘贴上去???找资料的时候碰见好多一模一样的东西 问题还尼玛的不能运行.比如在找AnimatedGifEncoder的时候  这个类里面貌似需要引用另外的两个类 但是另外的两个类从来没有人提到过???能不能有点出息...

找了半天 终于把dll找到了  特么的 全部都需要劳资注册 登录 有些还需要积分...有点醉.

这里给大家免费上传上去,呃..刚在传的时候发现不能选0???不过咱们是程序猿,把dom改一下就行了 把select里面的值改下就好了..


发上去 待审核,过一分钟刷新一下就好了 地址: http://download.csdn.net/download/u010067685/10146670

好了 现在jpg合成gif的dll也有了 又到了动手code的时候了

private void but2_Click(object sender, EventArgs e)        {            var path = txt1.Text;//原图            var fileName = path.Split('\\')[path.Split('\\').Length - 1];//文件名            var extension = fileName.Split('.')[fileName.Split('.').Length - 1];//后缀名            Image img = Image.FromFile(txt1.Text);            FrameDimension ImgFrmDim = new FrameDimension(img.FrameDimensionsList[0]);            //Determine the number of frames in the image            //Note that all images contain at least 1 frame,            //but an animated GIF will contain more than 1 frame.            int nFrameCount = img.GetFrameCount(ImgFrmDim);            // Save every frame into jpeg format            var paths = new List<string>();//存放路径的            //List<Image> imgs=new List<Image>();//保存每一帧 //以下是拆分步骤            for (int i = 0; i < nFrameCount; i++)            {                img.SelectActiveFrame(ImgFrmDim, i);                var temppath = string.Format(txt3.Text + "_{0}new.jpg", i);//把每一帧图片保存                //var temppath = string.Format(txt3.Text + "_new.jpg");                Graphics g1 = Graphics.FromImage(img);                //2:声明graphicse把img做为填充他的参数                //g1.DrawString("天天搞笑动图", new Font("楷体", 20, FontStyle.Regular), Brushes.Blue, 10, 10);                SolidBrush drawBrush = new SolidBrush(Color.FromArgb(255, 180, 0));                g1.DrawString("动图", new Font("楷体", 20, FontStyle.Regular), drawBrush, 10, 10);//加水印                //g1.DrawString("", new Font("楷体", 20, FontStyle.Regular),,10,10)                //img.Save(temppath, ImageFormat.Jpeg);                img.Save(temppath, ImageFormat.Jpeg);//保存 每次保存你可以去文件夹中去看到每张jpg                paths.Add(temppath);//保存路径//!!!! 用一个临时的变量 将img赋给 tempimg  imgs.add(tempimg); }//运行到这一步的时候 图片全部保存完毕            AnimatedGifEncoder MyGif = new AnimatedGifEncoder();            MyGif.Start(txt3.Text + "/" + fileName.Split('.')[0] + "_new." + extension);//保存路径            //MyGif.SetDelay(200);//帧率            //MyGif.SetSize(300, 300);//尺寸            MyGif.SetRepeat(0);//重复            foreach (var item in paths)            {                MyGif.AddFrame(Image.FromFile(item));//加入单张图片            }            //那这里就直接遍历 imgs就可以了 将item加入到 mygif里面去  MyGif.Finish();//到这一步的时候已经处理完毕 去文件夹下面看应该是能看到加了水印的gif了  这时候只需要把 paths里面的每一帧的图片全部删除就好了    }
好吧.在写这篇博客的时候 突然想起来 我是不是可以不保存   只需要用 List<Image> 将每一帧保存起来?  然后到最后的时候在遍历一下  看上面的存放路径的

这种方法你们看到了可以去试下 我觉得应该是没问题的。

后面发现这种方法貌似也有点不好的地方 太大了!

我原图gif 4.69M 处理i之后居然到9.74M了 

这里有点很奇怪.就是我这里231张图片总共才2.03M 保存成gif却那么大了???


然后我又去搜索 gif压缩

这时候重点来了!  看到了这篇文章 http://blog.csdn.net/pigkeli/article/details/17162243

看了下 发现完全不需要使用 第三方类库的!分解成每一帧之后合并 img有个saveAdd方法的!可以追加的!

看code

将刚才那篇文章 里面的代码 稍微改了下..就能用了

public static void YaSuo(string imgPath)        {            //原图              Image img = Image.FromFile(imgPath);            //不够100*100的不缩放              if (img.Width > 100 && img.Height > 100)            {                //新图第一帧                  Image new_img = new Bitmap(img.Width, img.Height);                //新图其他帧                  Image new_imgs = new Bitmap(img.Width, img.Height);                //新图第一帧GDI+绘图对象                  Graphics g_new_img = Graphics.FromImage(new_img);                //新图其他帧GDI+绘图对象                  Graphics g_new_imgs = Graphics.FromImage(new_imgs);                //配置新图第一帧GDI+绘图对象                  g_new_img.CompositingMode = CompositingMode.SourceCopy;                g_new_img.InterpolationMode = InterpolationMode.HighQualityBicubic;                g_new_img.PixelOffsetMode = PixelOffsetMode.HighQuality;                g_new_img.SmoothingMode = SmoothingMode.HighQuality;                g_new_img.Clear(Color.FromKnownColor(KnownColor.Transparent));                //配置其他帧GDI+绘图对象                  g_new_imgs.CompositingMode = CompositingMode.SourceCopy;                g_new_imgs.InterpolationMode = InterpolationMode.HighQualityBicubic;                g_new_imgs.PixelOffsetMode = PixelOffsetMode.HighQuality;                g_new_imgs.SmoothingMode = SmoothingMode.HighQuality;                g_new_imgs.Clear(Color.FromKnownColor(KnownColor.Transparent));                //遍历维数                  foreach (Guid gid in img.FrameDimensionsList)                {                    //因为是缩小GIF文件所以这里要设置为Time                      //如果是TIFF这里要设置为PAGE                      FrameDimension f = FrameDimension.Time;                    //获取总帧数                      int count = img.GetFrameCount(f);                    //保存标示参数                      System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.SaveFlag;                    //                      EncoderParameters ep = null;                    //图片编码、解码器                      ImageCodecInfo ici = null;                    //图片编码、解码器集合                      ImageCodecInfo[] icis = ImageCodecInfo.GetImageDecoders();                    //为 图片编码、解码器 对象 赋值                      foreach (ImageCodecInfo ic in icis)                    {                        if (ic.FormatID == ImageFormat.Gif.Guid)                        {                            ici = ic;                            break;                        }                    }                    //每一帧                      for (int c = 0; c < count; c++)                    {                        //选择由维度和索引指定的帧                          img.SelectActiveFrame(f, c);                        //第一帧                          if (c == 0)                        {                            //将原图第一帧画给新图第一帧                              g_new_img.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);                            //把振频和透明背景调色板等设置复制给新图第一帧                              for (int i = 0; i < img.PropertyItems.Length; i++)                            {                                new_img.SetPropertyItem(img.PropertyItems[i]);//选中                                Graphics g1 = Graphics.FromImage(new_img);//加水印                                SolidBrush drawBrush = new SolidBrush(Color.FromArgb(255, 180, 0));                                g1.DrawString("动图", new Font("楷体", 20, FontStyle.Regular), drawBrush, 10, 10);                            }                            ep = new EncoderParameters(1);                            //第一帧需要设置为MultiFrame                              ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);                            //保存第一帧                              new_img.Save(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/temp/" + Path.GetFileName(imgPath), ici, ep);//路径自己改下 这里是桌面的路径                        }                        //其他帧                          else                        {                            //把原图的其他帧画给新图的其他帧                              g_new_imgs.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);                            //把振频和透明背景调色板等设置复制给新图第一帧                              for (int i = 0; i < img.PropertyItems.Length; i++)                            {                                new_imgs.SetPropertyItem(img.PropertyItems[i]);//选中                                Graphics g1 = Graphics.FromImage(new_imgs);//加水印                                SolidBrush drawBrush = new SolidBrush(Color.FromArgb(255, 180, 0));                                g1.DrawString("动图", new Font("楷体", 20, FontStyle.Regular), drawBrush, 10, 10);                            }                            ep = new EncoderParameters(1);                            //如果是GIF这里设置为FrameDimensionTime                              //如果为TIFF则设置为FrameDimensionPage                              ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionTime);                            //向新图添加一帧                              new_img.SaveAdd(new_imgs, ep);                        }                    }                    ep = new EncoderParameters(1);                    //关闭多帧文件流                      ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);                    new_img.SaveAdd(ep);                }                //释放文件                  img.Dispose();                new_img.Dispose();                new_imgs.Dispose();                g_new_img.Dispose();                g_new_imgs.Dispose();            }        }

这种方法使用了之后发现 文件大小是小了点(6.47M)。。。


但是貌似有噪点了...不过还是能看的 没很大的影响

先不管了 折腾了一下午了...头有点疼....先这样吧......

给文中的三张图给你们去玩玩吧

好吧..传不上去...

你们自己去找素材玩吧..

哎  写东西主要是思路重要..不会写没关系.有百度 谷歌

当然会写肯定是最好..


百度 谷歌一下午 心累

尤其是那些博客搬运工的!!!!各种误导人.

2017-12.05 17.42


2017-12-07 更新一波

上面不是提到过 可以使用list<image>来 避免保存很多帧的图片嘛  我刚才试了下 没问题的

记得要将资源释放!!你们在操作的时候可以看任务管理器 内存暴涨啊...

以下是代码

 Image img = Image.FromFile(txt1.Text);            FrameDimension ImgFrmDim = new FrameDimension(img.FrameDimensionsList[0]);            //Determine the number of frames in the image            //Note that all images contain at least 1 frame,            //but an animated GIF will contain more than 1 frame.            int nFrameCount = img.GetFrameCount(ImgFrmDim);            // Save every frame into jpeg format            var paths = new List<string>();//存放路径的            List<Image> imgs = new List<Image>();            var left = 0;            //以下是拆分步骤            for (int i = 0; i < nFrameCount; i++)            {                img.SelectActiveFrame(ImgFrmDim, i);                var temppath = string.Format(txt3.Text + "_{0}new.jpg", i);//把每一帧图片保存                //var temppath = string.Format(txt3.Text + "_new.jpg");                Graphics g1 = Graphics.FromImage(img);                //2:声明graphicse把img做为填充他的参数                //g1.DrawString("天天搞笑动图", new Font("楷体", 20, FontStyle.Regular), Brushes.Blue, 10, 10);                SolidBrush drawBrush = new SolidBrush(Color.FromArgb(255, 180, 0));                if (left > img.Height)                {                    left--;                }                else                {                    left++;                }                g1.DrawString("动图", new Font("楷体", 20, FontStyle.Regular), drawBrush, 10, left);//加水印                //g1.DrawString("", new Font("楷体", 20, FontStyle.Regular),,10,10)                var tempimg = img.Clone() as Image;                imgs.Add(tempimg);//用复制就可以了                //tempimg.Dispose();//这里不能释放                //img.Save(temppath, ImageFormat.Jpeg);                //img.Save(temppath, ImageFormat.Jpeg);//保存                //paths.Add(temppath);//保存路径            }            img.Dispose();//释放资源            AnimatedGifEncoder MyGif = new AnimatedGifEncoder();            MyGif.Start(txt3.Text + "/" + fileName.Split('.')[0] + "_new." + extension);//保存路径            //MyGif.SetDelay(200);//帧率            //MyGif.SetSize(300, 300);//尺寸            MyGif.SetRepeat(0);//重复            //imgs.Reverse();//反序            foreach (var item in imgs)            {                MyGif.AddFrame(item);//加入单张图片                item.Dispose();//释放当前帧            }            //foreach (var item in paths)            //{            //    var tempimg = Image.FromFile(item);            //    MyGif.AddFrame(tempimg);//加入单张图片                            //    tempimg.Dispose();//释放资源            //}            MyGif.Finish();//到这一步已经保存好了

经过list<image>处理之后 gif也变小了...很奇怪...不知道什么情况



我现在再来研究下 为什么231张图片总共只有2M多 但是保存成gif怎么就有9M多了 (见上面介绍)








原创粉丝点击