2010-02-14 21 views
21

Al cambiar el tamaño de un widget Image en GWT, se cambia el tamaño del elemento de imagen, pero no se vuelve a escalar la imagen en la pantalla. Por lo tanto, la siguiente no funcionará:Escalar una imagen en GWT

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

Esto se debe a GWT implementa su widget de Image estableciendo el background-image del elemento HTML <img... /> como la imagen, el uso de CSS.

¿Cómo se obtiene la imagen real para cambiar el tamaño?

Respuesta

34

Vi this blog entry, que resuelve el problema utilizando GWT DataResource en lugar de ImageResource. Resulta que la misma técnica funcionará realmente con ImageResource, si lo usa de la siguiente manera:

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

Para mantener la relación de aspecto calcular que desea:

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

A partir de GWT 2.4, el uso (ver here):

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

Esto cambiará el tamaño de la imagen pero no mantendrá su relación de aspecto. – adranale

+2

@adranale: siempre se puede calcular la ración correcta (se agregó como esta es wiki de la comunidad) – Hurda

+0

No puedo cambiar el tamaño de la imagen de este método. No hace nada por mí:/ –

3

mi solución final fue para agregar un controlador de carga en el imagen para redimensionarla según las dimensiones de la imagen cargada (es decir, respetando la relación).

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"); 
       } 
      } 
     } 
    }); 

donde MAX_IMAGE_WIDTH y MAX_IMAGE_HEIGHT son constantes que determinan el tamaño máximo permitido de la imagen.

+0

La solución también se menciona aquí http://code.google.com/p/google-web-toolkit/issues/detail?id=3999 – zpon

+0

Me gusta su "si" porque impide duplicar el proceso. –

11

Si queremos hacer lo mismo en UiBinder.A partir de un recurso externo a continuación:

Por ejemplo tenemos en recource

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

En la plantilla UiBinder declaran el elemento <ui:with>:

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

y abajo:

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

en la versión anterior GWT:

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

pero ahora - en desuso.

No utilizar:

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

lástima pues no escala imágenes

+2

Solo como referencia, reemplaza "Ancho" y "Alto" con valores numéricos, por ej. JeremyFelix

1

escribí una clase que acepta un objeto ImageResource, y se puede ajustar el tamaño de pixel deseada de la imagen. Utiliza CSS background-position y CSS fondo de tamaño a achive el objetivo:

El código fuente de la ScalableImage clase es:

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)); 
    } 
} 

Se puede utilizar esta clase como sigue:

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

Si usa esta clase junto con un PushButton, entonces debe agregar PushButton al RootPanel, porque de lo contrario no se llama a la función onLoad(). Un ejemplo de código fuente se vería así:

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); 
     } 
+0

no es útil si uno tiene que pasar un 'ImageResource', p. utilizando algunos 'com.sencha.gxt.data.shared.IconProvider' para algún componente' Tree' con iconos –

0

De todo mi prueba, safeURI trabajar sólo si tiene una imagen UNO en su paquete ... Por lo tanto inútil para utilizarlo porque tiene uno cache.png por paquete, ¡así que no se optimiza nada!