Java: GC transparent background - java

I am using GC (org.eclipse.swt.graphics.GC) to combine some pictures into one image (using drawImage). The problem is that, by default GC has got white background. Is it possible to set background to transparent? Or any other solution to cut part from one picture and paste into second?

Simply, GC is a pen, pen can't control canvas's transparency. It just can only draws something on canvas. So, GC can't manipulate image itself, just GC can draw something on Image.
However, You can directly control transparency data with ImageData API.
You should have to know what there is no advanced drawing API except setPixel(x, y, pixel), setAlpha(x, y, alpha) on ImageData.

You could use a Canvas with no background
Canvas canvas = new Canvas(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
And then you could (like in this example) make one(or more) colors of the image transparent.
ImageData ideaData = new ImageData(getClass().getResourceAsStream("Idea.jpg"));
int whitePixel = ideaData.palette.getPixel(new RGB(255,255,255));
ideaData.transparentPixel = whitePixel;
Image transparentIdeaImage = new Image(display,ideaData);

Related

JavaFX Canvas distorts image

I am adding a frame to an image in JavaFX by first adding the frame to the canvas and then the image,
so that it overlaps and the image seems to have a frame.
For some reason my image gets distorted, it scales poorly and makes everything in it look "fat".
If I try to show the image in an ImageView (variable named "image" in the code) it looks normal,
so I tried to get the values (width and height) from the normal looking ImageView, yet still no luck:
Image i = new Image(path.toUri().toString());
image.setImage(i);
canvas.setWidth(image.getFitWidth() + 20);
canvas.setHeight(image.getFitHeight() + 20);
GraphicsContext gc1 = canvas.getGraphicsContext2D();
gc1.drawImage(rimage, 0, 0, image.getFitWidth() + 20, image.getFitHeight() + 20);
GraphicsContext gc = canvas.getGraphicsContext2D();
image.preserveRatioProperty();
gc.drawImage(i, 10, 10, image.getFitWidth(), image.getFitHeight());
Original image:
Framed and distorted (the head looks rounder):
I haven't tested this myself, but theres a few things I noticed about your code.
First, the line
image.preserveRatioProperty();
doesn't actually change any state for the ImageView, all it does is tell you whether or not the ImageView is set to preserve ratios.
what you probably want instead is:
image.setPreserveRatio(true);
which I believe will probably do what you want.
If it doesn't it might be because the image has already been loaded, so if this still doesn't work, try putting image.setPreserveRatio(true); before image.setImage(i);
Isn't the window just too wide for your image? Try to crop the image using another drawImage where you can define which part of the image you want to use. Or change the window size. Or use a width and height to draw with that is relative to the one in the image.

Android Drawing Performance - canvas.drawRect vs Bitmap Drawing

I am writing a particle based game that is mainly built by drawing lots of colored shapes.
Question 1)
For most of the enemy units I am drawing 4 layered rectangles by setting the paint and then drawing the rectangle through the canvas.
I was wondering if it is better to draw using bitmaps, or to draw using the canvas drawing tools? I could easily make a single image of the enemy unit that I wish to draw.
Question 2)
For the images that I have to draw to the screen, I was wondering how I need to load them?
Right now I have tons of .png images loaded like this:
direction1 = BitmapFactory.decodeStream(assetMgr.open("direction1.png"));
I've read that RGB565 is the fasted image type to draw to the screen. Microsoft Paint has some saving options, but for the most part programs only save as a bitmap, not a type of bitmap. If I was to start using that new format would I:
Make new images and use the same loading code.
Use the same images and add something like Bitmap bmp =
Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); to
convert from the initial loaded format to the RGB565 format.
Make new images and change my loading code.
Thanks for any help! It is very appreciated.
None. It is always better to use OpenGL and the only downside is
that it requires more energy from a battery because it's hardware
accelerated.
RGB565 means that image uses 16 bits so that's the
option you should look for. Don't convert anything, just create them
in the format you will be using.
If the Bitmap aren't moving frame-by-frame, you should try to reduce invalidate() method call. The canvas should only be re-drawn when changes are made and should be updated.

Save graphics as image?

I'm developing an app for BlackBerry with Eclipse and want to know if there is any way to save a picture that is drawn with a Graphics object...The app involves drawing a pie chart using Graphics.It works fine the first time I open the screen to display the chart but the next time I try to create the chart by calling the screen, it goes haywire.So I was wondering if I can save the chart as an image...that way I wont have to keep drawing over and over everytime I open the screen...Please help...Thanks in advance!
I understood you are using the java.awt.Graphics class, right?
Ensure you are drawing only on the AWT event thread.
Use
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// YOUR CODE
}
});
to run your saving code on the event thread. If you try to save from another thread, the image could get distorted if it is not drawn completely.
I don't know the blackberry API but you could take other aproach to your problem. You could do offscreen rendering. Create a BufferedImage, get a reference to its Graphics object, do the rendering and then save the BufferedImage as a png for example.
For example:
int width = 200, height = 200;
// TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed
// into integer pixels
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D ig2 = bi.createGraphics();
// Draw your chart
ImageIO.write(bi, "PNG", new File("yourImageName.PNG"));
This way you can do all your drawing once, saving it as a file or just in memory (depends on what you need) and then you just need either to load the image from the file or do g.drawImage() in your screen.
But as i said before i don't know if this applies to the Blackberry API it works for sure with the JDK/JRE in a desktop.

SWT: draw "icons" in table or tree cells

We are having a Swing application which we plan to port to SWT/JFace. The Swing application draws a lot of icons (javax.swing.Icon implementations) in trees and tables (icon left to the text). If I understood it correctly, SWT only can draw images (aka graphic files). What would be the simplest solution to paint the icon or entire table/tree cell? Thanks in advance.
Images can be loaded from graphic files, or they can be drawn in-memory.
Image image = new Image(Display.getCurrent(), width, height);
GC gc = new GC(image);
// draw icon using GC
gc.dispose();
As far as displaying them in tables/trees, the most direct approach is to set the image on the table/tree item:
TableItem item = ...
item.setImage(theImage);
There is one significant drawback to this approach however: on Windows, the first time you set an image on a table item, that image's height becomes the standard height for all items in the table. So if you set a larger image, it will be scaled down to the first image's size. If you set a smaller image, it will be scaled up.
If all your images are the same size, this will not be a problem.
However if you can not predict the size of the images in advance, I recommend using the custom draw API to render your table/tree items. This approach is definitely more intensive but gives you fine-grained control over the result.

Fast pixel plotting using SWT?

I'm looking for a fast and easy way to plot arbitrarily colored pixels in an SWT Canvas.
So far I'm using something like that:
// initialization:
GC gc = new GC(canvas);
// inside the drawing loop:
Color cc = new Color(display, r, g, b);
gc.setForeground(cc);
gc.drawPoint(x, y);
cc.dispose();
This is horribly horribly slow. it takes about a second and a half to fill a 300x300 canvas with pixels.
I could create an image off-screen, set the pixels in it and then draw the image. This will be faster but I specifically want the gradual painting effect of plotting the image pixel by pixel on the canvas.
I bet that what is killing performance is allocating and releasing 90,000 Color objects. Remember, in SWT, each Color object allocates native resources, which is why you have to dispose() it. This means each time you allocate and dispose a Color object, you have to transition from the JVM to native code and back.
Can you cache your Color instances while in the 300x300 pixel loop and then dispose of the objects after your loop? You'd need a somewhat intelligent cache that only holds a maximum of so many objects, and after that will dispose of some of its entries, but this should speed things up greatly.
You could draw several offscreen images where you gradually fill the 300x300 area. This way you can control how fast the image should appear.
Create a BufferedImage object:
BufferedImage bi = new new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
inside the drawing loop set your pixels:
bi.setRGB(x, y, int_rgb);
...
and finally display the buffered image:
g.drawImage(bi, 0, 0, null);
If you find setRGB() slow, you can access the bitmap data directly:
int[] raster = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
and later
raster[y * 300 + x] = int_rgb;

Categories

Resources