简体   繁体   中英

Scaling an image in Java Swt & memory consumption

i have a java swt application. In the resize method of a container i'd like to resize the image, which is shown using the following code. However seems like - even i dispose everything (really?) the memory consumption is increasing all the time... I can't find my mistake. Why and where this code eats up all my memory?

Here is the Resize-Listener:

tabCover.addListener(SWT.Resize, new Listener() {

        public void handleEvent(Event event) {
            // Set images: cover_front
            int width = tabCover.getSize().x - 30;
            int height = tabCover.getSize().y - 30;
            Image buffer_Coverfront;

            buffer_Coverfront = new Image(Display.getDefault(), filename);
            lblCoverfront.setImage(Helper.ImageScale(buffer_Coverfront, width, height));
            buffer_Coverfront.dispose();
            buffer_Coverfront = null;

        } // handleEvent
    }); // Listener

And here the scaling function:

public static Image ImageScale(Image image, int width, int height) {


    ImageData data = image.getImageData();

    // Some logic to keep the aspect ratio
    float img_height = data.height;
    float img_width = data.width;
    float container_height = height;
    float container_width = width;

    float dest_height_f = container_height;
    float factor = img_height / dest_height_f;

    int dest_width = (int) Math.floor(img_width / factor );
    int dest_height = (int) dest_height_f;

    if(dest_width > container_width) {
        dest_width = (int) container_width;
        factor = img_width / dest_width;
        dest_height = (int) Math.floor(img_height / factor);

    }

    // Image resize
    data = data.scaledTo(dest_width, dest_height);
    Image scaled = new Image(Display.getDefault(), data);
    image.dispose();
    return scaled;
}

As far as I can see from the handleEvent(...) method, you forget to dispose the old image.

tabCover.addListener(SWT.Resize, new Listener() {
    public void handleEvent(Event event) {
        // Set images: cover_front
        int width = tabCover.getSize().x - 30;
        int height = tabCover.getSize().y - 30;
        Image buffer_Coverfront;

        buffer_Coverfront = new Image(Display.getDefault(), filename);
        Image old = lblCoverfront.getImage();
        lblCoverfront.setImage(Helper.ImageScale(buffer_Coverfront, width, height));
        buffer_Coverfront.dispose();
        buffer_Coverfront = null;

        if (old != null) old.dispose();

    } // handleEvent
}); // Listener

The code above assumes that the image of the control is only set in this method. If you also set the initial image from, somewhere else, then the condition of the disposal have to be refined...

As i can't post the code in the comment, here it is:

tabCover.addListener(SWT.Resize, new Listener() {

        public void handleEvent(Event event) {
            // Set images: cover_front
            int width = tabCover.getSize().x - 30;
            int height = tabCover.getSize().y - 30;

                String filename_front = my_collection.getGlobal_path() + "Cover/" + selected_movie.getCover_front();

                try {
                    Image image = new Image(Display.getDefault(), filename_front);
                    Image scaled = Helper.ImageScale(image, width, height);
                    lblCoverfront.setImage(scaled);
                    image.dispose();
                    scaled.dispose();

                } catch (Exception e) {
                } // end try

        } // handleEvent
    }); // Listener

Thanks again to Tonny Madsen for the useful tip.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM