Масштабирование изображения в GWT
Изменение размера Image Виджет в GWT изменяет размер элемента изображения, но не перемасштабирует изображение на экране, Следовательно, следующее не будет работать:
Image image = new Image(myImageResource);
image.setHeight(newHeight);
image.setWidth(newWidth);
image.setPixelSize(newWidth, newHeight);
Это связано с тем, что GWT реализует свой Image, установив background-image
элемента HTML <img... />
в качестве изображения, используя CSS.
Как получить реальное изображение для изменения размера?
Ответы
Ответ 1
Я видел эту запись в блоге, которая решает проблему, используя GWT DataResource вместо ImageResource. Оказывается, что тот же самый метод будет работать с ImageResource, если вы его используете следующим образом:
Image image = new Image(myImageResource.getURL());
image.setPixelSize(getLength(), getHeight());
Чтобы сохранить соотношение сторон, выполните следующее:
Image image = new Image(myImageResource.getURL());
image.setPixelSize(newWidth, myImageResource.getHeight() * newWidth / myImageResource.getWidth());
Начиная с GWT 2.4, используйте (см. здесь):
Image image = new Image(myImageResource.getSafeUri());
image.setPixelSize(newWidth, myImageResource.getHeight() * newWidth / myImageResource.getWidth());
Ответ 2
Если мы хотим сделать то же самое в UIbinder. Из внешнего ресурса затем:
Например, мы имеем в recource
@Source("images/logo.png")
ImageResource getLogo();
В шаблоне UiBinder объявите элемент <ui:with>
:
<ui:with field='res' type='com.myapp.client.Resources'/>
и ниже:
<g:Image url='{res.getLogo.getSafeUri.asString}' pixelSize="Width, Height" />
в более старой версии GWT:
<g:Image url='{res.getLogo.getURL}' pixelSize="Width, Height" />
но теперь - устаревший.
Не использовать:
<g:Image resource='{res.getLogo}' pixelSize="Width, Height" />
поскольку он не масштабирует изображения
Ответ 3
Попробуйте виджет загрузчика изображений http://code.google.com/p/gwt-image-loader
Класс FitImage обеспечивает то, что вы ищете.
PS: применяйте также исправления от проблем, так как есть некоторые незначительные ошибки, которые я исправил
Ответ 4
Моим окончательным решением было добавить обработчик нагрузки на изображение, чтобы изменить его размер в соответствии с размерами загруженного изображения (т.е. учитывать отношение).
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");
}
}
}
});
где MAX_IMAGE_WIDTH
и MAX_IMAGE_HEIGHT
- константы, определяющие максимально допустимый размер изображения.
Ответ 5
Я написал класс, который принимает объект ImageResource, и вы можете установить желаемый размер пикселя изображения. Он использует CSS background-Position и CSS background-size для достижения цели:
Исходный код класса ScalableImage:
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));
}
}
Вы можете использовать этот класс следующим образом:
rootPanel.add(new ScalableImage(Images.Util.getImages().img0(), 60, 60));
Если вы используете этот класс вместе с PushButton, вам нужно добавить PushButton в RootPanel, потому что иначе функция onLoad() не вызывается.
Пример исходного кода будет выглядеть так:
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
Вот как я использую элемент canvas для масштабирования изображений с помощью HTML5.
http://code.google.com/p/gwt-examples/wiki/gwt_hmtl5
Брэндон Доннелсон
http://gwt-examples.googlecode.com
http://c.gawkat.com
Ответ 7
Из всего моего теста safeURI работает, только если у вас есть ОДИН образ в вашем комплекте... Поэтому бесполезно использовать его, потому что у вас есть один cache.png от Bundle, поэтому он ничего не оптимизирует!