Search code examples
javascalebufferedimagelibvlcvlcj

ArrayIndexOutOfBoundsException while trying to scale


Have been trying to scale down a view to different scale but i'm having some troubles. The context is inside a video player (using VLCJ).

This code is being used to scale the image but after the first frame the image stops updating with next image for some reason.

public void newFrameRecieved(int[] rgbBuffer)
{
    this.image.setRGB(0, 0, this.size.width, this.size.height, rgbBuffer, 0, this.size.width);


    after = new BufferedImage(this.getWidth(), this.getHeight(), this.image.getType());
    at = new AffineTransform();
    scalingFactorX = (double)this.getWidth()/ (double)this.image.getWidth();
    scalingFactorY = (double)this.getHeight()/ (double)this.image.getHeight();
    at.scale(scalingFactorX, scalingFactorY);
    scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
    this.image = scaleOp.filter(this.image, after);


    repaint();
}

If the middle part (all code between this.image.setRGB(......) and repaint();) is removed then it works(except the scaling part...)

Would really appreciate any help you guys can offer! The error recieved is the following:

JNA: Callback uk.co.caprica.vlcj.player.direct.DefaultDirectMediaPlayer$DisplayCallback@4516af24 threw the following exception:
java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    at sun.awt.image.IntegerInterleavedRaster.setDataElements(IntegerInterleavedRaster.java:301)
    at java.awt.image.BufferedImage.setRGB(BufferedImage.java:1059)
    at myVlcjWrapper.VideoSurfacePanel.newFrameRecieved(VideoSurfacePanel.java:65)

I understand the problem I'm just clueless as to how to fix it! Thanks!


Solution

  • After doing alot of error searching I ended up with this piece of working code!

    public void newFrameRecieved(int[] rgbBuffer, Dimension max)
    {
        before = new BufferedImage(max.width, max.height, BufferedImage.TYPE_INT_ARGB);
        before.setRGB(0, 0, max.width, max.height, rgbBuffer, 0, max.width);
        after = new BufferedImage(this.getWidth(), this.getHeight(), this.image.getType());
        at = new AffineTransform();
        scalingFactorX = (double)after.getWidth()/ (double)before.getWidth();
        scalingFactorY = (double)after.getHeight()/ (double)before.getHeight();
        at.scale(scalingFactorX, scalingFactorY);
        scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
        this.image = scaleOp.filter(before, after);
    
        repaint();
    }
    

    It's a minimal change but it did the trick! Thought it best to post it in case anyone ever finds their way here again. Thanks for the help guys! :)