效果展示
图片合成效果,不再演示,主要演示视频合成效果,因为是视频合成的原理就是先将每一张帧图合成图片,再用合成的图片制作成视频。
视频左右翻转合成效果
javacv实现视频翻转,合成
四宫格视频
更多视频展示链接
https://live.csdn.net/v/164980
注:原视频都来自于抖音。
添加jar依赖
Java spring boot项目或者maven项目的pom文件中添加以下依赖
-
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
-
<dependency>
-
<groupId>org.bytedeco
</groupId>
-
<artifactId>javacv-platform
</artifactId>
-
<version>1.5.5
</version>
-
</dependency>
代码展示
核心代码,单类实现,idea创建VideoSynthesis 类,复制粘贴下面代码,右键点击run运行主方法即可。
-
-
import org.bytedeco.javacv.FFmpegFrameGrabber;
-
import org.bytedeco.javacv.FFmpegFrameRecorder;
-
import org.bytedeco.javacv.Frame;
-
import org.bytedeco.javacv.Java2DFrameConverter;
-
-
import javax.imageio.ImageIO;
-
import java.awt.image.BufferedImage;
-
import java.io.File;
-
import java.io.IOException;
-
-
public
class VideoSynthesis {
-
-
-
final
static String videoFolderPath =
"C:/Users/tarzan/Desktop/video/";
-
final
static String videoName =
"video.mp4";
-
final
static String imageFolderPath =
"C:/Users/tarzan/Desktop/image/";
-
final
static String imageName1 =
"logo.jpg";
-
final
static String imageName2 =
"newlogo.jpg";
-
-
-
public static void main(String[] args) throws Exception {
-
-
-
// mergeImage(imageFolderPath + imageName1, imageFolderPath + imageName2);
-
mergeVideo(videoFolderPath + videoName);
-
-
}
-
-
-
//视频处理
-
public static void mergeVideo(String filePath) {
-
//抓取视频图像资源
-
FFmpegFrameGrabber videoGrabber =
new FFmpegFrameGrabber(filePath);
-
//抓取视频图像资源
-
FFmpegFrameGrabber audioGrabber =
new FFmpegFrameGrabber(filePath);
-
try {
-
videoGrabber.start();
-
audioGrabber.start();
-
//imageWidth和imageHeight根据需要合成的大小进行计算,比如左右2宫格宽度需要乘以2,四宫格宽、高都要乘以2,依次类推
-
FFmpegFrameRecorder recorder =
new FFmpegFrameRecorder(videoFolderPath +
"合成" + videoName, videoGrabber.getImageWidth()*
2, videoGrabber.getImageHeight(), videoGrabber.getAudioChannels());
-
recorder.start();
-
//处理图像
-
int videoSize = videoGrabber.getLengthInVideoFrames();
-
for (
int i =
0; i < videoSize; i++) {
-
Frame videoFrame = videoGrabber.grabImage();
-
if (videoFrame !=
null && videoFrame.image !=
null) {
-
System.out.println(
"视频共" + videoSize +
"帧,正处理第" + (i +
1) +
"帧图片");
-
Java2DFrameConverter converter =
new Java2DFrameConverter();
-
//获得原图帧
-
BufferedImage bi = converter.getBufferedImage(videoFrame);
-
//获得翻转图帧
-
BufferedImage bi2= imageFlipLR(bi);
-
//获得左右合成图帧
-
BufferedImage bufImg=mergeImageLR(bi,bi2);
-
// bufImg= mergeImageCenter(bufImg,bi);
-
recorder.record(converter.convert(bufImg));
-
}
-
}
-
//处理音频
-
int audioSize = audioGrabber.getLengthInAudioFrames();
-
for (
int i =
0; i < audioSize; i++) {
-
Frame audioFrame = audioGrabber.grabSamples();
-
if (audioFrame !=
null && audioFrame.samples !=
null) {
-
recorder.recordSamples(audioFrame.sampleRate, audioFrame.audioChannels, audioFrame.samples);
-
}
-
}
-
recorder.stop();
-
recorder.release();
-
videoGrabber.stop();
-
audioGrabber.stop();
-
}
catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
-
-
-
//合拼图片
-
public static void mergeImage(String imgPath1, String imgPath2) {
-
try {
-
BufferedImage bi_1 = ImageIO.read(
new File(imgPath1));
-
BufferedImage bi_2 = ImageIO.read(
new File(imgPath2));
-
BufferedImage mergeImage = mergeImageLR(bi_1, bi_2);
-
ImageIO.write(mergeImage,
"png",
new File(imageFolderPath + imageName1 +
"merge" + imageName2));
-
}
catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
-
//小图放到大图中间位置
-
public static BufferedImage mergeImageCenter(BufferedImage big, BufferedImage small) {
-
//new 一个新的图像
-
int w = small.getWidth();
-
int h = small.getHeight();
-
int wd = small.getWidth()/
2;
-
int hd = small.getHeight()/
2;
-
//像素一个一个复制过来
-
for (
int y =
0; y < h; y++) {
-
for (
int x =
0; x < w; x++) {
-
big.setRGB(x+wd, y+hd, small.getRGB(x, y));
-
}
-
}
-
return big;
-
}
-
-
//左右翻转
-
public static BufferedImage imageFlipLR(BufferedImage bi) {
-
int h = bi.getHeight();
-
int w = bi.getWidth();
-
BufferedImage image =
new BufferedImage(w, h, bi.getType());
-
//像素一个一个复制过来
-
for (
int y =
0; y < h; y++) {
-
for (
int x =
0; x < w; x++) {
-
image.setRGB(x, y, bi.getRGB(w-x-
1, y));
-
}
-
}
-
return image;
-
}
-
-
-
//左右合并
-
public static BufferedImage mergeImageLR(BufferedImage bi_1, BufferedImage bi_2) {
-
//new 一个新的图像
-
int w1 = bi_1.getWidth();
-
int w2 = bi_2.getWidth();
-
int h = bi_1.getHeight();
-
int w = w1 + w2;
-
BufferedImage bi =
new BufferedImage(w, h, bi_1.getType());
-
//像素一个一个复制过来
-
for (
int y =
0; y < h; y++) {
-
for (
int x =
0; x < w1; x++) {
-
bi.setRGB(x, y, bi_1.getRGB(x, y));
-
}
-
for (
int x =
0; x < w2; x++) {
-
bi.setRGB(w1 + x, y, bi_2.getRGB(x, y));
-
}
-
}
-
return bi;
-
}
-
-
//上下合并
-
public static BufferedImage mergeImageUD(BufferedImage bi_1, BufferedImage bi_2) {
-
//new 一个新的图像
-
int h1 = bi_1.getHeight();
-
int h2 = bi_2.getHeight();
-
int h = h1+h2;
-
int w = bi_1.getWidth();
-
BufferedImage bi =
new BufferedImage(w, h, bi_1.getType());
-
//像素一个一个复制过来
-
for (
int x =
0; x < w; x++) {
-
for (
int y =
0; y < h1; y++) {
-
bi.setRGB(x, y, bi_1.getRGB(x, y));
-
}
-
for (
int y =
0; y< h2; y++) {
-
bi.setRGB(x, h1+y, bi_2.getRGB(x, y));
-
}
-
}
-
return bi;
-
}
-
-
-
-
}
-
由于视频中的每一帧需要合成处理,过程可能辉有点慢,像文章中的视频,原视频3.93MB,经过翻转处理、左右合成处理的方法,处理时间月20s左右。
控制台运行输出日志
代码里还写了上下合成、小图放在大图的中心位置等方法,方便你处理各种需求。
相关文章推荐
《震惊,java仅用30行代码就实现了视频转音频的批量转换》
特别说明:如需转载此篇文章,请先关注本人后,注明作者名称,和文章链接地址即可。
转载:https://blog.csdn.net/weixin_40986713/article/details/117330543
查看评论