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.
Related
What I'm trying to do:
I'm trying to render a game board for a user using a canvas. The user
will be able to zoom.
Rendering the entire game board is impossible when the user is
zoomed in as the game board is very large. Instead I will render what
is onscreen every 1/30 sec.
I would like to create the illusion of the entire game board beings
inside a gui like the ScrollPane where the user can scroll with a
mouse.
In reality the ScrollPane will be linked to a single canvas exactly
the size of the viewport.
I'm not sure what the right way to go about this is. The scroll pane does not seem to have a property that allows you to pretend it has a large object in it. I could place a large canvas in the scroll pane but large canvases take up memory, as my crashes have suggested. Should I be using an AnchorPane or something? What's the proper way to do this?
It seems like putting an AnchorPane into the ScrollPane, setting that AnchorPane to the correct size (the size of the entire gameboard) works well to let the user scroll freely. From there all you have to do is put a canvas in the AnchorPane at the right place and keep moving it (and redrawing it) makes everything work out. To make it run smoothly I think you should render 100 to 500 pixels outside of the viewport of the ScrollPane. Here's some example code from my project:
public class GridViewPane {
/** ScrollPane that this grid exits in */
private ScrollPane gridScroll;
/** The anchor pane immediately inside of {#link #gridScroll}. The
* dimensions of this equals the dimensions of the {#link #can} if it was to
* render the entire grid at once */
private Pane gridView;
/** Exists in {#link #gridView} and is exactly the size of the viewport of
* {#link #gridScroll} */
private Canvas can;
/** A label the specifies what hex is currently moused-over */
private Label currentHexLabel;
public void update() {
// sets the canvas to the right size if needed
final Bounds viewportSize = gridScroll.getBoundsInLocal();
if (can == null || !can.getBoundsInLocal().equals(viewportSize)) {
can = new Canvas(viewportSize.getWidth(),
viewportSize.getHeight());
gc = can.getGraphicsContext2D();
}
// sets the anchorpane to the right size
final double[] dim = getPixleSizeOfGrid(w.columns(), w.rows(), r);
if (gridView == null) {
gridView = new AnchorPane();
gridScroll.setContent(gridView);
}
Bounds oldDim = gridView.getBoundsInLocal();
if (!(oldDim.getWidth() == dim[0]
&& oldDim.getHeight() == dim[1])) {
gridView.setPrefSize(dim[0], dim[1]);
}
// puts the canvas in the right position
if (!gridView.getChildren().contains(can))
gridView.getChildren().add(can);
double[] x = getXScreenRange();
double[] y = getYScreenRange();
can.relocate(x[0], y[0]);
// *********** Drawing Hexes ***********/
}
}
I am trying to use de Image Button on LIBGDX to create a button based on two images.
Using add to second image, works fine, but have one problem.
The images are of different sizes.
Note: I am testing with the same picture to see the result
Is there a way to correct this? Using some scale to the images?
levelsTexture = new Texture(Gdx.files.internal("level1.png"));
levels = new TextureRegion(levelsTexture).split(TILE_WIDTH, TILE_HEIGHT);
ImageButton levels_image = new ImageButton(new TextureRegionDrawable(new
TextureRegion(levels[0][0])));
levels_image.add(new Image (levels[0][0]));
stage.addActor(levels_image);
levels_image.setScale(2f);
The problem:
ImageButton is an extension of the Table class and typically the ImageButton images are set as the background. Using the "add" method for the second image like you did might work kind of, but it behaves differently than setting the background and it also might not be what you want if you want the the second image to also change when you click the button.
The easiest way to add two images to a single ImageButton would be to simply combine the two images in Photoshop (or equivalent) and use that single image on the ImageButton.
The more advanced (and more flexible) method would be to combine the two images programmatically and use this as the background for your ImageButton. This can be done by creating a custom class which extends BaseDrawable and have it take two Images in the constructor. If you want your images stacked on top of each other, set the minHeight of your custom drawable class to be the combined height of your two images. Then override the draw method and draw your two images on top of each other like this:
#Override
public void draw(Batch batch, float x, float y, float width, float height){
img1.getDrawable().draw(batch, x, y, img1.getWidth(), img1.getHeight());
img2.getDrawable().draw(batch, x, y+img1.getHeight(), img2.getWidth(), img2.getHeight());
}
}
The ImageButton takes a Drawable in its constructor, so you can pass this object right into the button when you create it and both of your Images should appear in the button and they will be treated as one.
I've done something similar to make a background for a table using multiple Images and this method works great.
I wrote my own SpriteButton class in which I implement this method for scaling my textures.
private Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
int original_width = imgSize.width;
int original_height = imgSize.height;
int bound_width = boundary.width;
int bound_height = boundary.height;
int new_width = original_width;
int new_height = original_height;
// first check if we need to scale width
if (original_width > bound_width) {
//scale width to fit
new_width = bound_width;
//scale height to maintain aspect ratio
new_height = (new_width * original_height) / original_width;
}
// then check if we need to scale even with the new height
if (new_height > bound_height) {
//scale height to fit instead
new_height = bound_height;
//scale width to maintain aspect ratio
new_width = (new_height * original_width) / original_height;
}
return new Dimension(new_width, new_height);
}
Then finally you draw the texture with the output dimension as as size to draw.
sb.begin();
sb.draw(this.texture2, this.x, this.y, dim_size_new.width, dim_size_new.height);
sb.end();
So you could technically draw the second image to the size of the the first image, if the first image size is correct.
Your implementation will look different from mine but you should be able to figure it out form here on out.
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.
i have one window panel and i want to set image in it.so i do,
Window window = new Window();
Panel panel = new Panel();
AbsolutePanel absolutePanel = new AbsolutePanel();
Image image = new Image("img/heat_map.jpg");
absolutePanel.add(image);
Image ap1Image = new Image("img/end.PNG");
ap1Image.getElement().getStyle().setMargin(1, Unit.PX);
absolutePanel.add(ap1Image);
panel.add(absolutePanel);
window.add(panel);
but i stuck in code as i can't overlap another small icon image on main image(heat_map).
i want onclick event on that icon image.but i can't overlap images in window panel.please help me out.
It seems that you using something like GXT not pure GWT. But anyway - AbsolutePanel should implement something like add(Widget, int left, int top) method so you need use it instead of simple add(widget)
First thing is in your code is you can not instantiate GWT Window Class since the constructor Window() is not visible.
Second thing is there is no add method in window class.
And finally to overlap your images one on another you need to apply Some CSS
(Z-index..positions )
CSS Divs overlapping, how do I force one above the other?
And finally
you can simply add a click handler to image.
imageIcon.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// Do something....
}
});
Good luck.
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);
}
});