我正在使用VideoSurfaceView来渲染过滤后的视频。我正在根据我的需要购买更改片段着色器。现在我想在更改为相同格式的文件(例如 mp4 - h264)后保存/渲染视频,但找不到如何做到这一点。
PS - 将纹理保存为位图并将位图保存到文件很容易,但我可以找到如何处理视频..
这里有高手吗?
我正在使用VideoSurfaceView来渲染过滤后的视频。我正在根据我的需要购买更改片段着色器。现在我想在更改为相同格式的文件(例如 mp4 - h264)后保存/渲染视频,但找不到如何做到这一点。
PS - 将纹理保存为位图并将位图保存到文件很容易,但我可以找到如何处理视频..
这里有高手吗?
正如您在评论中已经发现并说的那样,OpenGL 不能将多个帧导出为视频。
虽然如果您只是想过滤/处理视频的每一帧,那么您根本不需要 OpenGL,也不需要片段着色器,您可以简单地自己循环遍历所有像素。
现在假设您一次处理一帧视频,并且每一帧都是一个BufferedImage
,您当然可以使用任何您想要或提供的内容,只要您可以选择获取和设置像素。
我只是为您提供一种计算和应用过滤器的方法,您必须自己进行视频文件的解码和编码。
但回到BufferedImage
,首先我们要获取 中的所有像素BufferedImage
,我们使用以下方法来实现。
BufferedImage bi = ...; // Here you would get a frame from the video
int width = bi.getWidth();
int height = bi.getHeight();
int[] pixels = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
请注意,根据图像的类型以及图像是否包含透明度,DataBuffer
可能会在 aDataBufferInt
到等之间有所不同。您可以在 Oracle 文档中DataBufferByte
阅读不同之处,请单击此处。DataBuffers
现在只需遍历图像中的像素,我们就可以应用和创建任何类型的效果和过滤。
假设我们要创建一个灰度效果,也称为黑白效果,您可以通过以下方式实现。
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
final int index = x + y * width;
final int pixel = pixels[index];
final int alpha = (pixel >> 24) & 0xFF;
final int red = (pixel >> 16) & 0xFF;
final int green = (pixel >> 8) & 0xFF;
final int blue = pixel & 0xFF;
final int gray = (red + green + blue) / 3;
pixels[index] = alpha << 24 | gray << 16 | gray << 8 | gray;
}
}
现在您可以简单地再次保存图像,或者做任何您想做的事情。虽然你也可以使用和绘制BufferedImage
,因为BufferedImage
当然会改变像素数组BufferedImage
。
重要的是,如果要执行模糊效果,则在计算每个像素后将其存储到另一个数组中,因为执行模糊效果需要周围的像素。因此,如果在计算所有像素时替换旧的一次,一些像素将使用计算值而不是实际值。
上面的代码当然也适用于图像。
如果要获取存储在单个中的 RGBA 值,int
则可以执行以下操作。
int pixel = 0xFFFF8040; // This is a random testing value
int alpha = (pixel >> 24) & 0xFF; // Would equal 255 using the testing value
int red = (pixel >> 16) & 0xFF; // ... 255 ...
int green = (pixel >> 8) & 0xFF; // ... 128 ...
int blue = pixel & 0xFF; // ... 64 ...
然后,如果您有 RGBA 值并希望将它们组合成一个值,int
那么您可以执行以下操作。
int alpha = 255;
int red = 255;
int green = 128;
int blue = 64;
int pixel = alpha << 24 | red << 16 | green << 8 | blue;
如果你只有 RGB 值,那么你就做,red << 16 | green << 8 | blue
或者你做255 << 24 | red << 16 | green << 8 | blue