2010-02-14 10 views
21

Modifica delle dimensioni di un Image Il widget in GWT modifica le dimensioni dell'elemento immagine, ma non ridimensiona l'immagine sullo schermo. Pertanto, il seguente non funziona:Ridimensionamento di un'immagine in GWT

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

Questo perché GWT implementa il suo widget Image impostando il background-image dell'elemento HTML <img... /> come l'immagine, usando i CSS.

Come si può ridimensionare l'immagine effettiva?

risposta

34

Ho visto this blog entry, che risolve il problema utilizzando GWT DataResource anziché ImageResource. Si scopre che la stessa tecnica potrà mai funzionare con ImageResource, se lo si utilizza come segue:

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

Per mantenere le proporzioni calcolarlo come:

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

Come di GWT 2.4, l'uso (vedi here):

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

Questo ridimensionerà l'immagine ma non manterrà le proporzioni. – adranale

+2

@adranale: puoi sempre calcolare la razione corretta (aggiunta in quanto wiki della comunità) – Hurda

+0

Non riesco a ridimensionare l'immagine con questo metodo. Non fa niente per me:/ –

3

mia soluzione finale era quello di aggiungere un gestore di carico sul immagine per ridimensionarla in base alle dimensioni dell'immagine caricata (cioè rispettare il rapporto).

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

dove MAX_IMAGE_WIDTH e MAX_IMAGE_HEIGHT sono costanti che determinano la dimensione massima consentita dell'immagine.

+0

La soluzione è menzionata anche qui http://code.google.com/p/google-web-toolkit/issues/detail?id=3999 – zpon

+0

Mi piace il tuo "se" perché impedisce di raddoppiare l'evento. –

11

Se vogliamo fare lo stesso in UIbinder.Da una risorsa esterna, allora:

Per esempio abbiamo in Recource

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

Nel modello UiBinder dichiarare l'elemento <ui:with>:

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

e sotto:

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

nella vecchia versione GWT:

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

ma ora - Deprecato.

Non utilizzare:

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

siccome non scala le immagini

+2

Solo per riferimento, si sostituiscono 'Larghezza' e 'Altezza' con valori numerici es. JeremyFelix

1

ho scritto una classe che accetta un oggetto ImageResource, ed è possibile impostare la dimensione in pixel desiderata dell'immagine. Esso utilizza CSS background-position e CSS background-size per achive l'obiettivo:

Il codice sorgente del ScalableImage classe è:

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

È possibile utilizzare questa classe come segue:

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

Se si utilizza questa classe insieme a un PushButton, allora si deve aggiungere il PushButton al RootPanel, perché altrimenti la funzione onLoad() non viene chiamata. Un esempio di codice sorgente sarebbe simile:

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

non utile se si deve passare un 'ImageResource', ad es. usando alcuni 'com.sencha.gxt.data.shared.IconProvider' per un componente' Tree' con icone –

0

Da tutta la mia prova, safeURI funziona solo se si dispone di un'immagine ONE in fascio ... Quindi inutile usarlo perché si dispone di uno cache.png dal Fascio, quindi è ottimizzare nulla!