I am trying to get frames from a gif using OpenCV. I found Convert each animated GIF frame to a separate BufferedImage and used the second suggestion. I modified it slightly to return an array of Mats instead of BufferedImages.
I tried two methods to get bufferedImages
from the gif. Each presented different problems.
With the previous thread’s suggestion
BufferedImage fImage=ir.read(i);
The program calls a “ArrayIndexOutOfBoundsException: 4096”
With the original code from the previous thread.
BufferedImage fImage=ir.getRawImageType(i).createBufferedImage(ir.getWidth(i),ir.getHeight(i));
Each frame is a monotone color(not all black though) and the mat derived from the BufferedImage is empty.
System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); ArrayList<Mat> frames = new ArrayList<Mat>(); ImageReader ir = new GIFImageReader(new GIFImageReaderSpi()); ir.setInput(ImageIO.createImageInputStream(new File("ronPaulTestImage.gif"))); for(int i = 0; i < ir.getNumImages(true); i++){ BufferedImage fImage=ir.read(i); //BufferedImage fImage=ir.getRawImageType(i).createBufferedImage(ir.getWidth(i), ir.getHeight(i)); fImage = toBufferedImageOfType(fImage, BufferedImage.TYPE_3BYTE_BGR); //byte[] pixels = ((DataBufferByte) r.getRaster().getDataBuffer()).getData(); Mat m=new Mat(); //m.put(0,0,pixels); m.put(0, 0,((DataBufferByte) fImage.getRaster().getDataBuffer()).getData()); if(i==40){ //a test, writes the mat and the image at the specified frame to files, exits ImageIO.write(fImage,"jpg",new File("TestError.jpg")); Imgcodecs.imwrite("TestErrorMat.jpg",m); System.exit(0); }
Here is the gif I used
Advertisement
Answer
I am not using libs for gif nor Java nor OpenCV but the ArrayIndexOutOfBoundsException: 4096
means that the dictionary is not cleared properly. The gif of yours is buggy I tested it and it contains errors not enough clear codes are present for some frames. If your GIF decoder does not check/handle such case then it simply crash because its dictionary growth more then GIF limit 4096/12bit
Try another GIF not some buggy ones …
have tested your gif and it has around 7 clear codes per frame and contains 941 errors in total (absence of clear code resulting in dictionary overrun)
If you have source code for the GIF decoder
then just find part of decoder where new item is added to dictionary and add
if (dictionary_items<4096)
before it … If you ignore the wrong entries the image looks still OK most likely the encoder in which this was created was not properly coded.