import javax.imageio.ImageIO;
import org.bytedeco.javacv.FFmpegFrameGrabber;
public class FrameData
{
int count = 0;
int picWidth;
int picHeight;
BufferedImage img = null;
//GET FRAME COUNT
public int gf_count(int numofFrames, BufferedImage[] frameArray, String fileLocationsent, String videoNamesent) throws IOException
{
String fileLocation = fileLocationsent;
String videoName = videoNamesent;
int frameNums = numofFrames;
int totFrames = 0;
FFmpegFrameGrabber grab = new FFmpegFrameGrabber(fileLocation + videoName);
try { grab.start(); }
catch (Exception e) { System.out.println("Unable to grab frames"); }
for(int i = 0 ; i < frameNums ; i++)
{
try
{
frameArray[i]= grab.grab().getBufferedImage();
totFrames = i;
File outputfile = new File(fileLocation + "GrayScaledImage" + i + ".jpg");
ImageIO.write(frameArray[i], "jpg", outputfile);
}
catch (Exception e) { /*e.printStackTrace();*/ }
}//END for
return totFrames;
}//END METHOD long getFrameCount()
希望有人可以向我解释一下...... 我刚学java,所以这里... 我编写了这段代码来计算.mov文件中的帧数,并测试我生成的缓冲图像数组我生成的图像文件。正如代码一样,它按计划运行......问题出在捕获后,如果我将缓冲图像作为文件发送出来,它们似乎只是第一个图像。见下面的例子......
for(int i = 0 ; i < frameNums ; i++)
{
try
{
frameArray[i]= grab.grab().getBufferedImage();
totFrames = i;
File outputfile = new File(fileLocation + "GrayScaledImage" + i + ".jpg");
ImageIO.write(frameArray[i], "jpg", outputfile);
}
catch (Exception e) { /*e.printStackTrace();*/ }
}//END for
现在,如果我将其改为......
for(int i = 0 ; i < frameNums ; i++)
{
try
{
frameArray[i]= grab.grab().getBufferedImage();
totFrames = i; catch (Exception e) { /*e.printStackTrace();*/ }}
for(int j = 0; j < frameNums; j++)
{
File outputfile = new File(fileLocation + "GrayScaledImage" + j + ".jpg");
ImageIO.write(frameArray[j], "jpg", outputfile);
}
我不明白为什么我会反复获得相同的图像。 如果需要进一步的信息,请知道,这是我在线的第一个编程问题...通常找到我正在寻找的其他人提出的问题。无法找到这个。 谢谢你的时间 肯
答案 0 :(得分:0)
问题是grab()。getBufferedImage()每次都在同一个缓冲区中工作。在循环中为该缓冲区分配引用时,您将分配对相同缓冲区numofFrames次的引用。那你写的不是第一帧,而是最后一帧。为了解决这个问题,你需要做一个&#34;深层复制&#34; BufferedImage。请参阅以下代码:
public class FrameData {
BufferedImage img;
Graphics2D g2;
// GET FRAME COUNT
public int gf_count(int numFrames, BufferedImage[] frameArray, String fileLocation, String videoName) throws Exception, IOException {
Java2DFrameConverter converter = new Java2DFrameConverter();
int totFrames = 0;
img = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
g2 = img.createGraphics();
FFmpegFrameGrabber grab = new FFmpegFrameGrabber(fileLocation + videoName);
grab.start();
for (int i = 0; i < numFrames; i++) {
frameArray[i] = deepCopy(converter.convert(grab.grab()));
totFrames = i;
}
for (int j = 0; j < totFrames; j++) {
File outputfile = new File(fileLocation + "TImage" + j + ".jpg");
ImageIO.write(frameArray[j], "jpg", outputfile);
}
return totFrames;
}// END METHOD long getFrameCount()
BufferedImage deepCopy(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
// This does what the converter.convert seems to do, which
// is decode an image into the same place over and over.
// if you don't copy the result every time, then you end up
// with an array of references to the same last frame.
BufferedImage draw() {
g2.setColor(new Color(-1));
g2.fillRect(0, 0, 100, 50);
g2.setColor(new Color(0));
g2.drawLine(0, 0, (int)(Math.random()*100.0), (int)(Math.random()*50.0));
return img;
}
public static void main(String... args) throws Exception, IOException {
new FrameData().run();
}
private void run() throws Exception, IOException {
BufferedImage images[] = new BufferedImage[50];
gf_count(50, images, "C:/Users/karl/Videos/", "dance.mpg");
}
}
我已经包含了一个draw()
方法,该方法通过示例显示如何在同一个BufferedImage中重复完成工作,以防您想要复制问题。
当然还有其他方法可以进行深层复制,并且可能存在显示问题的方法。参考:How do you clone a BufferedImage。
PS&GT;我更新了代码以使用bytedeco库的1.1版本。