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