Scaling an Image in GWT

倖福魔咒の 提交于 2019-11-26 16:33:18

问题


Changing the size of an Image Widget in GWT changes the size of the image element, but does not rescale the image on the screen. Therefore, the following will not work:

Image image = new Image(myImageResource);
image.setHeight(newHeight);
image.setWidth(newWidth);
image.setPixelSize(newWidth, newHeight);

This is because GWT implements its Image widget by setting the background-image of the HTML <img... /> element as the image, using CSS.

How does one get the actual image to resize?


回答1:


I saw this blog entry, which solves the problem by using a GWT DataResource instead of ImageResource. It turns out that the same technique will actually work with ImageResource, if you use it as follows:

Image image = new Image(myImageResource.getURL());
image.setPixelSize(getLength(), getHeight());

To keep aspect ratio calculate it like:

Image image = new Image(myImageResource.getURL());
image.setPixelSize(newWidth, myImageResource.getHeight() * newWidth / myImageResource.getWidth());

As of GWT 2.4, use (see here):

Image image = new Image(myImageResource.getSafeUri());
image.setPixelSize(newWidth, myImageResource.getHeight() * newWidth / myImageResource.getWidth());



回答2:


If we want to do the same in UIbinder. From an external resource then :

For example we have in recource

@Source("images/logo.png")
ImageResource getLogo();

In UiBinder template declare the <ui:with> element:

<ui:with field='res' type='com.myapp.client.Resources'/>

and below:

<g:Image url='{res.getLogo.getSafeUri.asString}'  pixelSize="Width, Height" />

in older GWT version:

<g:Image url='{res.getLogo.getURL}'  pixelSize="Width, Height" />

but now - Deprecated.

Do not use:

<g:Image resource='{res.getLogo}' pixelSize="Width, Height" />

becouse it doesn't scale images




回答3:


Try the image loader widget http://code.google.com/p/gwt-image-loader The FitImage class provides what you are looking for.

PS: apply also patches from issues, as there are some minor bugs which I have fixed

  • http://code.google.com/p/gwt-image-loader/issues/detail?id=1
  • http://code.google.com/p/gwt-image-loader/issues/detail?id=3



回答4:


my final solution was to add a load handler on the image to resize it according to the dimensions of the loaded image (i.e. respectnig the ratio).

image.addLoadHandler(new LoadHandler() {
        @Override
        public void onLoad(LoadEvent event) {
            Element element = event.getRelativeElement();
            if (element == image.getElement()) {
                int originalHeight = image.getOffsetHeight();
                int originalWidth = image.getOffsetWidth();
                if (originalHeight > originalWidth) {
                    image.setHeight(MAX_IMAGE_HEIGHT + "px");
                } else {
                    image.setWidth(MAX_IMAGE_WIDTH + "px");
                }
            }
        }
    });

where MAX_IMAGE_WIDTH and MAX_IMAGE_HEIGHT are constants that determine the maximum allowed size of the image.




回答5:


I wrote a class which accepts a ImageResource object, and you can set the wanted Pixel size of the Image. It uses CSS background-Position and CSS background-size to achive the aim:

The source code of the class ScalableImage is:

package de.tu_freiberg.informatik.vonwenckstern.client;
// class is written by Michael von Wenckstern, and is also used in ist diploma Thesis
// (this is only for my super visor, that he does not think I copied it from stackoverflow
// without mention the source) - this class is free to use for every body

import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Image;

public class ScalableImage extends Image {
    private int width;
    private int height;
    private ImageResource res;

    public ScalableImage(ImageResource res, int width, int height) {
        this.setUrl(res.getSafeUri());
        this.res = res;
        this.width = width;
        this.height = height;
    }

    @Override
    public void onLoad() {
        int widthOfBigImage = this.getOffsetWidth();
        int heightOfBigImage = this.getOffsetHeight();
        double scaleX = width / res.getWidth();
        double scaleY = height / res.getHeight();
        this.setResource(res);
        DOM.setStyleAttribute(getElement(), "backgroundPosition", Integer.toString((int) (res.getLeft() * -1 * scaleX))+"px "+
                Integer.toString((int) (res.getTop() * -1 * scaleY))+"px ");
        DOM.setStyleAttribute(getElement(), "backgroundSize", Integer.toString((int) (widthOfBigImage * scaleX))+"px "+
                Integer.toString((int) (heightOfBigImage * scaleY))+"px ");
        this.setPixelSize((int) (res.getWidth()* scaleX), (int) (res.getHeight() * scaleY));
    }
}

You can use this class as followed:

rootPanel.add(new ScalableImage(Images.Util.getImages().img0(), 60, 60));

If you use this class together with a PushButton, than you have to add the PushButton to the RootPanel, because otherwise the onLoad() function is not called. An example source code would look like:

for(ImageResource imRes: latexIconsClientBundle) {
            ScalableImage im = new ScalableImage(imRes, 60, 60);
            RootPanel.get().add(im); // PushButton class does not fire onAttach event, so we need to attach the image to the RootPanel
            PushButton btn = new PushButton(im);
            btn.setPixelSize(60, 60);
            if(++col > 9) {
                row++;
                col = 0;
            }
            this.setWidget(row, col, btn);
        }



回答6:


Here is how I use the canvas element to scale images using HTML5.

http://code.google.com/p/gwt-examples/wiki/gwt_hmtl5

Brandon Donnelson http://gwt-examples.googlecode.com http://c.gawkat.com




回答7:


From all my test, safeURI work only if you have ONE image in your bundle...So useless to use it because you have one cache.png by Bundle, so it is optimize nothing !



来源:https://stackoverflow.com/questions/2260458/scaling-an-image-in-gwt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!