Java+OpenCV+Idea实现动态‘少帅’动态代码视频效果

程序由Java开发 代码简单易上手 附上:

完整代码下载地址:链接 提取码: wf5u 

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * @author 大毛不会编程
 */
public class ShaoShuai extends JPanel {

    private static final char[] BINARY_CHARS = {'@', '#', '%', '*', '+', '=', '-', ':', '.', ' '};
    private String[] binaryFrameLines;
    private final VideoCapture capture;
    private BufferedImage frameImage;

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public ShaoShuai(String videoPath) {
        capture = new VideoCapture(videoPath);
        if (!capture.isOpened()) {
            System.out.println("无法打开视频: " + videoPath);
            System.exit(1);
        }

        Timer timer = new Timer(25, e -> {
            Mat frame = new Mat();
            if (capture.read(frame)) {
                frameImage = matToBufferedImage(frame);
                if (frameImage != null) {
                    Dimension windowSize = getSize();
                    // 调整二进制图像大小为更小尺寸
                    BufferedImage resizedImage = resizeImage(frameImage, windowSize.width / 8, windowSize.height / 17);
                    binaryFrameLines = convertToBinary(resizedImage);
                }
                repaint();
            } else {
                ((Timer) e.getSource()).stop();
            }
        });
        timer.start();
    }

    private BufferedImage matToBufferedImage(Mat mat) {
        int width = mat.cols();
        int height = mat.rows();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        int[] data = new int[width * height];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                double[] pixel = mat.get(y, x);
                int b = (int) pixel[0];
                int g = (int) pixel[1];
                int r = (int) pixel[2];
                data[y * width + x] = (r << 16) | (g << 8) | b;
            }
        }

        image.setRGB(0, 0, width, height, data, 0, width);
        return image;
    }

    private BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, width, height, null);
        g.dispose();
        return resizedImage;
    }

    private String[] convertToBinary(BufferedImage image) {
        String[] binaryArt = new String[image.getHeight()];

        for (int y = 0; y < image.getHeight(); y++) {
            StringBuilder line = new StringBuilder();
            for (int x = 0; x < image.getWidth(); x++) {
                Color pixelColor = new Color(image.getRGB(x, y));
                int grayValue = (pixelColor.getRed() + pixelColor.getGreen() + pixelColor.getBlue()) / 3;
                int charIndex = mapGrayToBinaryIndex(grayValue);
                line.append(BINARY_CHARS[charIndex]);
            }
            binaryArt[y] = line.toString();
        }
        return binaryArt;
    }

    private int mapGrayToBinaryIndex(int grayValue) {
        return (int) Math.floor(grayValue / (255.0 / (BINARY_CHARS.length - 1)));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, getWidth(), getHeight());

        if (binaryFrameLines != null) {
            g.setFont(new Font("Monospaced", Font.BOLD, 13));
            g.setColor(Color.LIGHT_GRAY);
            int lineHeight = g.getFontMetrics().getHeight();
            for (int i = 0; i < binaryFrameLines.length; i++) {
                g.drawString(binaryFrameLines[i], 10, (i + 1) * lineHeight);
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(1000, 800);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("少帅");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(Color.BLACK);
        String videoPath = "E:\\JavaCode\\untitled1\\src\\ss.mp4"; //此处改成自己的视频地址
        ShaoShuai panel = new ShaoShuai(videoPath);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

效果展示图:

8dfd2cfe5cae4124a16617b66234e794.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值