using GWTCanvas with ImageResource - gwt

I want to use the clientBundle capability of GWT to load only 1 image, which is composed of many sprites, with GWTCanvas. My initial take was to just convert the ImageResource into an ImageElement, but apparently that doesn't seem to work:
public interface Bundle implements ClientBundle{
public static Bundle INSTANCE = GWT.create(Bundle .class);
#Source("/img/tile1.png")
public ImageResource tile1()
}
final GWTCanvas canvas = new GWTCanvas(400,400);
canvas.drawImage(ImageElement.as(new Image(Bundle.INSTANCE.tile1()).getElement()), 0, 0);
i tried adding the Image to RootPanel first (to force a load), but that doesn't seem to work too. Perhaps the timings are incorrect. Does anyone have a clue as to how I can draw an imageResource using GWTCanvas?

This works: (GWT 2.4)
// load:
SafeUri uri= imageResource.getSafeUri();
ImageElement imgElement= ImageElement.as((new Image(uri)).getElement());
// render
context.drawImage(imgElement, 0, 0);

You can get the image from a bundle using a data URI, but you'll need to manage the asynchrony as you would with a remote image.
final Image image = new Image(resources.imageResource().getURL());
RootPanel.get().add(image);
image.setVisible(false);
fetchedImage.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
context.drawImage(ImageElement.as(image.getElement()), 0, 0);
}
});

Using ClientBundled image in the way you want isn't possible. Images combined to one big image are displayed as background images which is based on the feature of the browser to show only part of an image. GWT calls this 'clipped' mode. So when you try to get the element of that image, the actual src tag is empty as the image is a background image. If you want to display images on the Canvas it must be an actual link to an image.

You might try using the ImageResource's getURL() method when you create the image:
canvas.drawImage(ImageElement.as(new Image(Bundle.INSTANCE.tile1().getUrl()).getElement(), 0, 0);
I was having the same problem when using a ClientBundle with GWT 2.2.0's Canvas type and this fixed it for me.

They are correct, just use getSafeUri() instead of getURL()

The solution of Tom Fishman didn't work for me, because the images weren't loaded at the time when i called canvas.drawImage(). This solution works (also for big images):
// Create Image
SafeUri uri = resource.getSafeUri();
Utils.console("URI: "+ uri);
final Image img = new Image(uri);
// Add the image to the RootPanel to force the image to be loaded.
RootPanel.get().add(img);
// The image has to be added to the canvas after the image has been loaded.
// Otherwise the bounding box of the image is 0,0,0,0 and nothing will be drawn.
img.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
// Create the image element.
ImageElement imgElement = ImageElement.as(img.getElement());
// Render the image on the canvas.
context2d.drawImage(imgElement, offsetX, offsetY);
// Delete the image from the root panel.
RootPanel.get().remove(img);
}
});

Related

Eclipse label decorator can't draw off the image

I'm trying to create a label decorator to add an icon to the top left of my file icons. I see that the little red X can be drawn off of the edge of the icon, but my radiation symbol is cut off at the edge.
l
#Override
public Image decorateImage(Image image, Object element) {
Image failureImg = Activator.imageDescriptorFromPlugin(IMAGE PATH).createImage();
GC gc = new GC(image);
gc.drawImage(failureImg, 0, 0, failureImg.getImageData().width, failureImg.getImageData().height,
0, 0, 11, 11);
gc.dispose();
return image;
}
Any ideas on how to draw outside of the bounds of the file icon?
It is easier to use a lightweight label decorator (implement ILightweightLabelDecorator and specify lightweight="true" in the extension point).
You can then add the decoration image with:
#Override
public void decorate(final Object element, final IDecoration decoration)
{
ImageDescriptor imageDescriptor = Activator.imageDescriptorFromPlugin(IMAGE PATH);
decoration.addOverlay(imageDescriptor, IDecoration.TOP_LEFT);
}
Since lightweight decorators are run in a background thread they also make the UI more responsive.
Note: Your code is creating Image objects and not arranging for them to be disposed - this leaks resource handles. The lightweight decorator does not have this issue.

Using new UI Image component to show a image on web in Unity 4.6

I'm trying to use the new UI objects in Unity 4.6 to create a ranking screen where I download information about the users and show them. Among those informations I have an URL pointing to their picture.
Before the UI tools I was doing it with GUITexture and using the www.LoadImageIntoTexture method, but there doesn't seem to be a similar solution for UI Images. Using a GUITexture with a Rect Transform doesn't seem to work.
Should I just manually download the image and load it into the image or is there a similiar solution as with using WWW class?
The new Image component takes requires a sprite to render.
What should work is download a PNG texture using the WWW class, then creating a sprite and finally assigning it to the component.
Here's some sample code.
Create a new Monobehaviour, paste below code into it (I called my script "LoadImageToButton")
Create a new UIButton
Attach the Monobehaviour created in Step 1 to the Button
In the Button's "OnClick" event, Drag the button created in Step 2 (this same button) into the GameObject field
Select the "LoadImage" function as the function to call for the OnClick event. (In my case it was "LoadImageToButton.LoadImage")
Hit Play, click the button. You should see the button's image change (It looks terrible, but it works)
See the pictures attached for actual results.
//This is the method you call if you use the "OnClick" event from a button click.
//We cannot call the Coroutine function below, because it breaks the rule for
//the event system. i.e. Must be a return type of void.
public void LoadImage () {
//Call the actual loading method
StartCoroutine(RealLoadImage());
}
//This is where the actual code is executed
private IEnumerator RealLoadImage () {
//A URL where the image is stored
string url = "http://www.axsu3d.com/DLs/AxSWP8Plugin/TileLogo.png";
//Call the WWW class constructor
WWW imageURLWWW = new WWW(url);
//Wait for the download
yield return imageURLWWW;
//Simple check to see if there's indeed a texture available
if(imageURLWWW.texture != null) {
//Construct a new Sprite
Sprite sprite = new Sprite();
//Create a new sprite using the Texture2D from the url.
//Note that the 400 parameter is the width and height.
//Adjust accordingly
sprite = Sprite.Create(imageURLWWW.texture, new Rect(0, 0, 400, 400), Vector2.zero);
//Assign the sprite to the Image Component
GetComponent<UnityEngine.UI.Image>().sprite = sprite;
}
yield return null;
}

What the easiest way to add a image to my GWT application

I have .jpg file that I want to display. I have some Horizontal and Vertical panels and I would like to have it somewhere in there. It is a fairly large image but I would like to make a class or an object that will scale it down for me.
My first thought was to just put it in a Horizontal Panel like so but that does not seem to work as I intended
HorizontalPanel picturePanel = new HorizontalPanel();
picturePanel.setPixelSize(600, 300);
picturePanel.addStyleName("pic");
Css.css
.pic
{
background: url(images/mypic.jpg);
height: auto;
width: auto;
}
I'd like to set the pixel size of an object (panel) and add an image to that panel so that it fits within the bounds (while making sure the ratio is the same as in the picture) so I can programatically add it to a panel somewhere.
public interface MyResources extends ClientBundle {
MyResources INSTANCE = GWT.create(MyResources.class);
#Source("logo.png")
ImageResource logo();
}
in your view class
Image logo = new Image(MyResources.INSTANCE.logo());
add image to panel;
set resolution to your panel and also set the same to your image by using
setPixelSize(int,int);
This works:
Image image = new Image();
Image.setWidth("100px");
image.setUrl('http://127.0.0.1:8888/images/accounts.png');
Loads image form local server and will limit size of image.

Optimal way of drawing hexagonal map with GWT

I'm looking for best solution - I'm drawing a hexagonal map (Civilization like :) ) for my browser based game in GWT. Currently I'm drawing it on canvas which basically works.
However - I'm also able to slide map left,right,down and up to see another fragment of the map. In such situation I'm forced to redraw the whole map - which doesn't look too good, and will probaly cause preformance issues when the map gets more complex.
Is there a better approach for that? Some library? Or maybe I should make every hex a button like widget. so I could be able to move it instead creating from the scratch... but what about different resolutions then... I'm affraid the map could tear apart sometimes...
You could try doing it will simple DIVs (FlowPanel, HTMLPanel, etc) and style the hexagons using CSS. See this tutorial: http://jtauber.github.com/articles/css-hexagon.html
There are some neat suggestions here as well: html/css hexagon with image inside and hexagonal shaped cells in html
You could draw the entire map (usually just the relatively static background, not the animations!) in a hidden canvas, and then copy the parts you need to your visible canvas:
final Canvas hiddenCanvas = buildCanvas(1000, 1000);
drawHexPattern(hiddenCanvas);
// don't add the hiddenCanvas to your DOM
final Canvas visibleCanvas = buildCanvas(320, 200);
RootPanel.get().add(visibleCanvas); // add the visibleCanvas to the DOM
showArea(hiddenCanvas, visibleCanvas, 0, 0);
...
showArea(hiddenCanvas, visibleCanvas, 20, 10);
...
With a showArea() method like
private void showArea(final Canvas hiddenCanvas, final Canvas visibleCanvas,
final double x, final double y) {
final Context2d hiddenCtx = hiddenCanvas.getContext2d();
final Context2d visibleCtx = visibleCanvas.getContext2d();
final ImageData imageData = hiddenCtx.getImageData(x, y,
visibleCanvas.getCoordinateSpaceWidth(),
visibleCanvas.getCoordinateSpaceHeight());
visibleCtx.putImageData(imageData, 0, 0);
}
I created a pastebin with a working example: http://pastebin.com/tPN2093a

Gwt Image original size

I use an Image object to load a png image as a thumbnail by calling its setPixelSize() method to resize the image. I also need to retrieve the original size of the image as integers at some point. How can I get the original sizes (width, height) of the image?
ok i found a workaround: I use a dummy container (SimplePanel) and load the image without scaling save its real dimensions and then remove the container from the parent and discard the new Image object. I don't know if this a good workaround, but it works. Although i would like to know if there is another way...
problem of the workaround: I have a droplist from which i can select logical folders (which contain images). When i select a new folder, and the new set of images is loaded on display, then i get 0 for width and 0 for height.
private void getTrueSize(String fullUrl) {
Image trueImage = new Image();
this.tstCon.add(trueImage);
trueImage.setUrl(fullUrl);
this.trueHeight = trueImage.getHeight();
this.trueWidth = trueImage.getWidth();
//this.tstCon.remove(trueImage);
//trueImage = null;
GWT.log("Image [" + this.imgTitle + "] -> height=" + this.trueHeight + " -> width=" + this.trueWidth);//
}
Extend the Image class and implement onAttach() method. This method is called when a widget is attached to the browser's document.
public class Thumb extends Image {
public Thumb(){
super();
}
protected void onAttach(){
Window.alert(getOffsetHeight()+" "+getOffsetWidth()); //this should give you the original value
setPixelSize(10,10); // this should be the visible value
super.onAttach();
}
}
if this doesn't work, try implementing onLoad() instead of onAttach(), since onLoad() will be called after the image is added to DOM so that it definately should work.
Its the easiest way to create a new hidden Image (placed absolute outside the viewport) and read the size. There is a JavaScript lib that can read the exif data of the image but this would be overkill in this case.
Read naturalHeight and naturalWidth of the image element after image load.
public Panel() {
image = new Image();
image.addLoadHandler(this::onLoad);
}
private void onLoad(#SuppressWarnings("unused") LoadEvent event) {
origImageWidth = getNaturalWidth(image);
origImageHeight = getNaturalHeight(image);
}
private static int getNaturalHeight(Image img) {
return img.getElement().getPropertyInt("naturalHeight"); //$NON-NLS-1$
}
private static int getNaturalWidth(Image img) {
return img.getElement().getPropertyInt("naturalWidth"); //$NON-NLS-1$
}