Масштабирование изображения в GWT
-
20-09-2019 - |
Вопрос
Изменение размера Изображение Виджет в GWT меняет размер элемента изображения, но не масштабирует изображение на экране.Поэтому следующее не будет работать:
Image image = new Image(myImageResource);
image.setHeight(newHeight);
image.setWidth(newWidth);
image.setPixelSize(newWidth, newHeight);
Это потому, что GWT реализует свою Изображение виджет, установив background-image
HTML <img... />
элемент в качестве изображения, используя CSS.
Как можно изменить размер фактического изображения?
Решение
Я видел эта запись в блоге, который решает проблему за счет использования 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());
Другие советы
Если мы хотим сделать то же самое в UIbinder.Затем с внешнего ресурса:
Например, у нас есть ресурс
@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" />
потому что он не масштабирует изображения
Попробуйте виджет загрузки изображений http://code.google.com/p/gwt-image-loader Класс FitImage предоставляет то, что вы ищете.
ПС:примените также исправления от проблем, так как есть некоторые мелкие ошибки, которые я исправил
моим окончательным решением было добавить к изображению обработчик загрузки, чтобы изменить его размер в соответствии с размерами загруженного изображения (т.е.соблюдая соотношение).
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
— константы, определяющие максимально допустимый размер изображения.
Я написал класс, который принимает объект ImageResource, и вы можете установить желаемый размер изображения в пикселях.Для достижения цели он использует CSS-положение фона и размер фона CSS:
Исходный код класса 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);
}
Вот как я использую элемент холста для масштабирования изображений с помощью HTML5.
http://code.google.com/p/gwt-examples/wiki/gwt_hmtl5
Брэндон Доннельсонhttp://gwt-examples.googlecode.comhttp://c.gawkat.com
Согласно всем моим тестам, SafeURI работает только в том случае, если у вас есть ОДНО изображение в вашем пакете... Использовать его бесполезно, потому что у вас есть один кэш.png от Bundle, поэтому ничего не оптимизируется!