Java原来可以这么玩!CV视频合成处理,制作2宫格4宫格多宫格的视频

Posted 洛阳泰山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java原来可以这么玩!CV视频合成处理,制作2宫格4宫格多宫格的视频相关的知识,希望对你有一定的参考价值。

效果展示

图片合成效果,不再演示,主要演示视频合成效果,因为是视频合成的原理就是先将每一张帧图合成图片,再用合成的图片制作成视频。

视频左右翻转合成效果

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行代码就实现了视频转音频的批量转换》

特别说明:如需转载此篇文章,请先关注本人后,注明作者名称,和文章链接地址即可。

以上是关于Java原来可以这么玩!CV视频合成处理,制作2宫格4宫格多宫格的视频的主要内容,如果未能解决你的问题,请参考以下文章

百万点赞怎么来?Python批量制作抖音的卡点视频原来这么简单!

java中HelloWorld原来还可以这样玩

原来RocketMQ中间件可以这么玩

github和gitlab首页原来还可以这样玩,酷毙了

github和gitlab首页原来还可以这样玩,酷毙了

创建Topic原来还能这样玩,真绝了!!!(附视频)