Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 318|回复: 0

[图像处理学习]GIF解码和编码操作库源码

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-30 23:57:09 | 显示全部楼层 |阅读模式
    GIF解码和编码操作库源码,共有四个类文件(请下载): 1.AnimatedGifEncoder.java
    2.GifDecoder.java
    3.LZWEncoder.java
    4.NeuQuant.java
    简单应用:
    1. import javax.imageio.ImageIO;
    2. import java.io.*;
    3. import java.awt.image.*;
    4. public class Testgif{
    5. public static void main(String args[]){
    6.    try{
    7.          BufferedImage src = ImageIO.read(new File("c:/work/1.jpg")); // 读入文件
    8.          BufferedImage src1 = ImageIO.read(new File("c:/work/2.jpg")); // 读入文件
    9.          BufferedImage src2 = ImageIO.read(new File("c:/work/3.jpg")); // 读入文件
    10.                     AnimatedGifEncoder e = new AnimatedGifEncoder();
    11.                     e.setRepeat(0);
    12.                     e.start("c:/work/laoma.gif");
    13.                     e.setDelay(3000);   // 1 frame per sec
    14.                     e.addFrame(src);
    15.                     e.setDelay(1000);
    16.                     e.addFrame(src1);
    17.                     e.setDelay(100);
    18.                     e.addFrame(src2);
    19.                     e.finish();
    20.             }catch(IOException e){
    21.                 e.printStackTrace();
    22.             }
    23. }
    24. }
    25. 下面的例子来自:http://blog.csdn.net/ideas/archive/2006/08/25/1116198.aspx
    26. 作者: ideas
    27. 1 多张jpg图合成gif动画
    复制代码
        /** *//**
          * 把多张jpg图片合成一张
          * @param pic String[] 多个jpg文件名 包含路径
          * @param newPic String 生成的gif文件名 包含路径
          */   
      
       
       

         
       

         
       
      
       private synchronized void jpgToGif(String pic[], String newPic) ...{
            try ...{
                 AnimatedGifEncoder e = new AnimatedGifEncoder();
                 e.setRepeat(0);
                 e.start(newPic);
                 BufferedImage src[] = new BufferedImage[pic.length];
                for (int i = 0; i < src.length; i++) ...{
                     e.setDelay(200); //设置播放的延迟时间
                     src = ImageIO.read(new File(pic)); // 读入需要播放的jpg文件
                     e.addFrame(src);  //添加到帧中
                 }
                 e.finish();
            } catch (Exception e) ...{
                 System.out.println( "jpgToGif Failed:");
                 e.printStackTrace();
             }
         }
    2 gif动画分解成多张jpg     /** *//**
          * 把gif图片按帧拆分成jpg图片         
          * @param gifName String 小gif图片(路径+名称)
          * @param path String 生成小jpg图片的路径
          * @return String[] 返回生成小jpg图片的名称
          */
         private synchronized String[] splitGif(String gifName,String path) ...{
            try ...{
                 GifDecoder decoder = new GifDecoder();
                 decoder.read(gifName);
                 int n = decoder.getFrameCount(); //得到frame的个数
                 String[] subPic = new String[n];
                 String tag = this.getTag();
                for (int i = 0; i < n; i++) ...{
                     BufferedImage frame = decoder.getFrame(i); //得到帧
                     //int delay = decoder.getDelay(i); //得到延迟时间
                     //生成小的JPG文件
                     subPic = path + String.value(i)+ ".jpg";
                     FileOutputStream out = new FileOutputStream(subPic);
                     ImageIO.write(frame, "jpeg", out);
                     JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);   
                    encoder.encode(frame); //存盘
                   out.flush();
                    out.close();
                 }
                 return subPic;
            } catch (Exception e) ...{
                 System.out.println( "splitGif Failed!");
                 e.printStackTrace();
                 return null;
             }
         } 3 根据提供的文字生成jpg图片     /** *//**
          * 根据提供的文字生成jpg图片
          * @param s String  文字
          * @param smallWidth int  每个字的宽度和高度是一样的
          * @param bgcolor Color  背景色
          * @param fontcolor Color  字色
          * @param fontPath String 字体文件
          * @param jpgname String jpg图片名
          * @return
          */
        private String createJpgByFont(String s, int smallWidth,Color bgcolor,Color fontcolor,String fontPath,String jpgname) ...{
            try ...{                                                                                
                 BufferedImage bimage = new BufferedImage(s.length()*smallWidth,
                                                              smallWidth,BufferedImage.TYPE_INT_RGB);
                 Graphics2D g = bimage.createGraphics();
                 g.setColor(bgcolor); //背景色
                 g.fillRect(0, 0, smallWidth, smallWidth); //画一个矩形

                 //去除锯齿(当设置的字体过大的时候,会出现锯齿)
                 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

                 g.setColor(fontcolor); //字的颜色
                 File file = new File(fontPath);  //字体文件

                 //根据字体文件所在位置,创建新的字体对象(此语句在jdk1.5下面才支持)  
                 Font font = Font.createFont(Font.TRUETYPE_FONT, file);
      
                //font.deriveFont(float f)复制当前 Font 对象并应用新设置字体的大小
                 g.setFont(font.deriveFont((float) smallWidth));

                 g.drawString(s,0, smallWidth); //在指定坐标除添加文字
                 g.dispose();
                 FileOutputStream out = new FileOutputStream(jpgname); //指定输出文件
                 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
                 param.setQuality(50f, true);
                 encoder.encode(bimage, param); //存盘
                 out.flush();
                 out.close();
            } catch (Exception e) ...{
                 System.out.println( "createJpgByFont Failed!");
                 e.printStackTrace();
             }
         }
    4 多张小jpg图合成一张大JPG图,在这里对大图只作宽度限制,不做高度限制     /** *//**
          * 将多个小图片合成一张大jpg图  (小的jpg图片按照行列顺序平铺)
          * @param smallJPG ArrayList 一组小的jpg图片
          * @param bigWidth int 大图宽度
          * @param smallWidth int  单个文字生成的小图的宽度和高度是一致的
          * @return
          */
         private void createBigJPG(ArrayList smallJPG, int bigWidth,
                                    int smallHeigh,Color bgColor ,String picName) ...{
            try ...{
                 if (bigWidth < smallWidth) //如果大图片的高度比小图片的高度还小 直接返回
                     return;
                 int colCount = bigWidth / smallWidth; //每行放置的字数
                 int leftMargin = (int) ((bigWidth - colCount * smallWidth) / 2f); //左边距
                 int rowCount = smallJPG.size();  //小图行数
                 int setWidth = bigWidth; //每列中间不留空隙,只留左右边距
                 int setHeight = smallWidth * rowCount ;

                 //按照大图片宽高绘制一个背景图片
                 BufferedImage bufImage = new BufferedImage(setWidth, setHeight,
                         BufferedImage.TYPE_INT_RGB);

                 Graphics2D g = bufImage.createGraphics();
                 g.setColor(bgColor); //背景的颜色
                 g.fillRect(0, 0, setWidth, setHeight);
                 int y = 0; //纵坐标
                for (int i = 0; i < rowCount; i++) ...{ //遍历每行
                     ArrayList col = (ArrayList) (smallJPG.get(i));
                     int x = leftMargin; //横坐标  可能会出现左边距
                    for (int j = 0; j < col.size(); j++) ...{
                         String jpgname = (String) (col.get(j));
                         ImageIcon icon = new ImageIcon(jpgname);
                         Image img = icon.getImage();
                         int imgWidth = img.getHeight(null);
                         g.drawImage(img, x, y, null);
                         x += imgWidth;
                     }
                     y += (smallWidth);  
                 }
                 g.dispose();
                 FileOutputStream out = new FileOutputStream(picName);  //指定输出文件
                 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  //设置文件格式
                 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufImage); //从图片缓冲中读取
                 param.setQuality(50f, true);
                 encoder.encode(bufImage, param); //存盘
                 out.flush();
                 out.close();
            } catch (Exception e) ...{
                 System.out.println( "createBigJPG Failed!");
                 e.printStackTrace();   
             }
         }
    注: (1)AnimatedGifEncoder和GifDecoder,以及这两个类涉及到的相关类,在网上搜索一下就可以找到。 (2)在linux系统下,如果你想支持更多系统外的字体,使用下面两句话,可以不用为系统添加字体,直接把字体文件拷贝到相应位置即可,但是需要jdk1.5环境。

    File file = new File(fontPath);  //字体文件
    Font font = Font.createFont(Font.TRUETYPE_FONT, file); //根据字体文件所在位置,创建新的字体对象

    如果是jdk1.5以下版本则需要为系统添加字体,因为createFont(int fontFormat, File fontFile)
    这个方法,是从1.5才开始有的。 (3)g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    我在测试中发现,当设置的字体过大的时候,会出现很明星的锯齿,后来在网上找到了这个解决方法。 (4)有了以上几个方法,就可以做出更好看的闪信了。我也是因为需求才写下这些方法的,美工做了一些热门词汇的gif图片,在短信转彩信遇到这些词汇时,要使用提供的图片替换文字。
      

      
      
       
       

         
       

         
       
      



    源码下载:http://file.javaxxz.com/2014/10/30/235709265.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 21:48 , Processed in 0.428103 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表