java实现5毛钱特效

1 篇文章 0 订阅

看到一个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;
    }

}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值