How can I turn a series of images into a video using JCodec?

不羁的心 提交于 2019-12-01 00:41:27

I had a lot of issues with jcodec's RgbToYuv420() transform.
I used my own function to transform my RGB BufferedImage to Yuv420.
One issue I had was that RgbToYuv420 averages the computed upix and vpix values, and it was causing the colors in my mp4 to be all wonky.

// make a YUV420J out of BufferedImage pixels
private Picture makeFrame(BufferedImage bi, ColorSpace cs)
{   
    DataBuffer imgdata = bi.getRaster().getDataBuffer();
    int[] ypix = new int[imgdata.getSize()];
    int[] upix = new int[ imgdata.getSize() >> 2 ];
    int[] vpix = new int[ imgdata.getSize() >> 2 ];
    int ipx = 0, uvoff = 0;

    for (int h = 0; h < bi.getHeight(); h++) {
        for (int w = 0; w < bi.getWidth();  w++) {
            int elem = imgdata.getElem(ipx);
            int r = 0x0ff & (elem >>> 16);
            int g = 0x0ff & (elem >>> 8);
            int b = 0x0ff & elem;
            ypix[ipx] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
            if ((0 != w % 2) && (0 != h % 2)) {
                upix[uvoff] = (( -38 * r + -74 * g + 112 * b) >> 8) + 128;
                vpix[uvoff] = (( 112 * r + -94 * g + -18 * b) >> 8) + 128;
                uvoff++;
            }
            ipx++;
        }
    }
    int[][] pix = { ypix, upix, vpix, null };
    return new Picture(bi.getWidth(), bi.getHeight(), pix, ColorSpace.YUV420J);
}

With 0.2.0 there is now https://github.com/jcodec/jcodec/blob/master/javase/src/main/java/org/jcodec/api/awt/AWTSequenceEncoder8Bit.java

This example creates a MP4 with a fixed background and overlaid animation. No sound.

    AWTSequenceEncoder8Bit enc = AWTSequenceEncoder8Bit.create2997Fps(outputMovieFile); 
    int framesToEncode = (int) (29.97 * durationInSeconds);
    java.awt.image.BufferedImage image = ...(some background image)

    for (int frameIndx = 0, x = 0, y = 0, incX = speed, incY = speed; frameIndx < framesToEncode; frameIndx++, x += incX, y += incY) {
        Graphics g = image.getGraphics();
        g.setColor(Color.YELLOW);
        if (x >= image.getWidth() - ballSize) incX = -speed;
        if (y >= image.getHeight() - ballSize) incY = -speed;
        if (x <= 0) incX = speed;
        if (y <= 0) incY = speed;
        g.fillOval(x, y, ballSize, ballSize);
        enc.encodeImage(image);
    }
    enc.finish();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!