zoukankan      html  css  js  c++  java
  • java图片处理——多张图片合成一张Gif图片并播放或Gif拆分成多张图片

    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[i] = ImageIO.read(new File(pic[i])); // 读入需要播放的jpg文件 e.addFrame(src[i]); //添加到帧中 } 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[i] = path + String.value(i)+ ".jpg";  
                   FileOutputStream out = new FileOutputStream(subPic[i]);  
                   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);  //字体文件
                Font font = Font.createFont(Font.TRUETYPE_FONT, file); //根据字体文件所在位置,创建新的字体对象(此语句在jdk1.5下面才支持)  
                g.setFont(font.deriveFont((float) smallWidth));   //font.deriveFont(float f)复制当前 Font 对象并应用新设置字体的大小
                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();    
            }
        }

    5、根据指定字符串生成图片

    //根据str,font的样式以及输出文件目录
    public static void createImage(String str,Font font,File outFile) throws Exception{
      //获取font的样式应用在str上的整个矩形
      Rectangle2D r=font.getStringBounds(str, new FontRenderContext(AffineTransform.getScaleInstance(1, 1),false,false));
      int unitHeight=(int)Math.floor(r.getHeight());//获取单个字符的高度
      //获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
      int width=(int)Math.round(r.getWidth())+1;
      int height=unitHeight+3;//把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
      //创建图片
      BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
      Graphics g=image.getGraphics();
      g.setColor(Color.WHITE);
      g.fillRect(0, 0, width, height);//先用白色填充整张图片,也就是背景
      g.setColor(Color.black);//在换成黑色
      g.setFont(font);//设置画笔字体
      g.drawString(str, 0, font.getSize());//画出字符串
      g.dispose();
      ImageIO.write(image, "png", outFile);//输出png图片
    }

    6、多个图片叠加

    public static void combineImage(List<String> urlList, int width,
                int height, String destPath, String imgFormat) throws IOException {
            BufferedImage combinedImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics g = combinedImage.getGraphics();
            for (String urlStr : urlList) {
                URL url = new URL(urlStr);
                URLConnection conn = url.openConnection();
                conn.setReadTimeout(10 * 1000);
                InputStream in = conn.getInputStream();
                BufferedImage image = ImageIO.read(in);
                g.drawImage(image, 0, 0, width, height, null);
            }
            ImageIO.write(combinedImage, imgFormat, new File(destPath));
    }

    注:

    (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://blog.csdn.net/ycb1689/article/details/8071714

  • 相关阅读:
    (引)spring学习笔记1.什么是控制反转
    Arduino 各种模块篇 步进电机 step motor 舵机 servo 直流电机 总复习
    Raspberry Pi Wireless Adaptor
    Pyramid 使用总结1
    Arduino 各种模块篇 人体红外感应模块 proximity sensor
    Pyramid 使用总结2
    Webcam Streaming Desktop Recording on Linux for ubuntu or its destros
    Arduino 各种模块篇 步进电机 step motor( 不用库,不用shield, 纯)
    Arduino 各种模块篇 motor shield 电机扩展板(舵机、直流电机、步进电机party)
    转载 stepper motors
  • 原文地址:https://www.cnblogs.com/dreammyle/p/4843365.html
Copyright © 2011-2022 走看看