java實現5毛錢特效

看到一個python五毛錢特效

原文:https://blog.csdn.net/ZackSock/article/details/105558172

那不得java也來搞一搞對吧。

å¨è¿éæå¥å¾çæè¿°      

勉強五毛特效吧~~~~直接上源碼吧

有個maven依賴 用於生成gif圖片

<dependency>
    <groupId>com.madgag</groupId>
    <artifactId>animated-gif-lib</artifactId>
    <version>1.2</version>
</dependency>
package com.joefan.video.video;

import com.madgag.gif.fmsware.AnimatedGifEncoder;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;

import javax.imageio.ImageIO;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;

public class Gif {

    public static void main (String[] args) {
        String src = "C:\\Users\\joefan\\Desktop\\pic\\src.gif" ;
        String tarFile = "C:\\Users\\joefan\\Desktop\\pic\\tar.gif";
        String bag = "C:\\Users\\joefan\\Desktop\\pic\\bag.jpg";
        handle(src, tarFile, bag);
    }

    /**
     * 將gif圖片替換背景
     * @param src gif圖片
     * @param target 替換背景後生成的文件命
     * @param bag 替換的背景圖片
     */
    public static boolean handle(String src, String target, String bag) {
        FileImageInputStream in;
        try {
            //原gif信息
            in = new FileImageInputStream(new File(src));
            ImageReaderSpi readerSpi = new GIFImageReaderSpi();
            GIFImageReader gifReader = (GIFImageReader) readerSpi.createReaderInstance();
            gifReader.setInput(in);
            //幀數
            int num = gifReader.getNumImages(true);

            if (num > 0) {
                // 新gif操作類 用於生成一個新的gif
                AnimatedGifEncoder encoder = new AnimatedGifEncoder();
                encoder.setRepeat(0);
                encoder.start(target);
                //新的幀圖片數組
                BufferedImage[] frames = new BufferedImage[num];

                for (int i = 0; i < num; i++) {
                    //讀取原幀圖片並去除背景 生成無背景透明圖
                    BufferedImage bufferedImage = convert(gifReader.read(i));
                    //讀取背景圖片
                    BufferedImage bagBufferedImage = ImageIO.read(new File(bag));

                    //合併幀圖 並轉換爲輸入流
                    BufferedImage bufferedImage1 = merge(bufferedImage, bagBufferedImage);
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ImageIO.write(bufferedImage1, "jpg", os);
                    InputStream is = new ByteArrayInputStream(os.toByteArray());

                    //寫入gif幀
                    encoder.setDelay(200); //設置播放的延遲時間
                    frames[i] = ImageIO.read(is); // 讀入需要播放的jpg文件
                    encoder.addFrame(frames[i]);  //添加到幀中
                }
                encoder.finish();

            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return false;
    }

    /**
     * 去除純色背景圖片
     * @param image image
     */
    private static BufferedImage convert(BufferedImage image) {
        //將背景色變透明
        ImageIcon imageIcon = new ImageIcon(image);
        int w = imageIcon.getIconWidth();
        int h = imageIcon.getIconHeight();
        BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
        g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());

        int alpha;
        for (int i = bufferedImage.getMinX(); i < w; i++) {

            for (int j = bufferedImage.getMinY(); j < h; j++) {
                int rgb = bufferedImage.getRGB(i, j);
                //以背景色左上角最小像素做參考系
                int RGB = bufferedImage.getRGB(bufferedImage.getMinX(), bufferedImage.getMinY());
                int r = (rgb & 0xff0000) >> 16;
                int g = (rgb & 0xff00) >> 8;
                int b = (rgb & 0xff);
                int R = (RGB & 0xff0000) >> 16;
                int G = (RGB & 0xff00) >> 8;
                int B = (RGB & 0xff);

                //a爲色差範圍值,漸變色邊緣處理,數值需要具體測試,50左右的效果比較可以
                int a = 45;
                if (Math.abs(R - r) < a && Math.abs(G - g) < a && Math.abs(B - b) < a) {
                    alpha = 0;
                } else{
                    alpha = 255;
                }

                rgb = (alpha << 24) | (rgb & 0x00ffffff);
                bufferedImage.setRGB(i, j, rgb);
            }
        }

        g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
        return bufferedImage;
    }

    /**
     * 圖片合併
     * @param source 原圖
     * @param bag 背景圖
     */
    private static BufferedImage merge(BufferedImage source, BufferedImage bag) throws Exception {
        if (bag.getWidth() < source.getWidth() || bag.getHeight() < source.getHeight()) {
            throw new Exception("背景圖片太小");
        }

        Graphics2D g;

        int startWidth = ( bag.getWidth() - source.getWidth() ) / 2;
        int startHeight= ( bag.getHeight() - source.getHeight() ) / 2;

        try {
            int w = source.getWidth();
            int h = source.getHeight();

            g = bag.createGraphics();
            g.drawImage(source, startWidth, startHeight, w, h, null);
            g.dispose();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return bag;
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章