I have a few pictures, i know their position and size... How do I place my images in one ImageView? (as shown in the picture below)
you have two options:
create a relative layout, include 4 images views and set one image to each bitmap
that's a bit more complex, use Bitmap.createBitmap(int width, int height, Bitmap.Config config); to create a mutable bitmap with the size you want, create a new canvas with new Canvas(bitmap); to create a canvas into that bitmap, and use canvas.drawBitmap(...) to draw the 4 bitmaps into the final one.
Related
I need to resize an image to specific dimensions, 100 by 100 pixels for example, in JavaFX.
How can I achieve that? Could the Image or the ImageView class be used for this purpose?
Yes, using an ImageView. Just call
ImageView imageView = new ImageView("...");
imageView.setFitHeight(100);
imageView.setFitWidth(100);
By default, it will not preserve the width:height ratio: you can make it do so with
imageView.setPreserveRatio(true);
Alternately you can resize the Image directly on loading:
Image image = new Image("my/res/flower.png", 100, 100, false, false);
Resizing the image on loading is useful for things like thumbnails of larger images as the memory required is lower than storing the larger image data representation in memory.
I am loading an external image with JavaFX:
Image tile = new Image(imageFile.toURI().toURL().toString(),width, height, true,true);
You need to supply the width and height. How can I get the image's width and height?
Now, I know that the width and height of a PNG image are determined by the bytes from 12 to 20 or something like that, so technically you could open a byte stream and interpret the bytes. However, this seems overkill for the simple task of drawing an image in my JavaFX application. Is there not a way to draw an image with its full size without asking me to supply the dimensions?
Just create the Image using a constructor which does not include dimensions (e.g. new Image(url)):
Image image = new Image(url);
I have two RenderedImages. I want to do an Overlay Operation with these two images and therefore they need to match in data type and the number of bands.
The problem I have is that one image has 3 bands (RGB) and the second image has 4 bands (ARGB).
My question is how can I add an Alpha Channel to the first image so I can do the Overlay Operation?
EDIT
Ok, I found a method of adding an Alpha Channel to the first image. Below is the code. I simply created a single banded constant image and merged it with my first image.
ParameterBlock pb = new ParameterBlock();
pb.add(new Float(finalImage.getWidth())).add(new Float(finalImage.getHeight()));
pb.add(new Byte[] {new Byte((byte)0xFF)});
RenderedImage alpha = JAI.create("constant", pb);
finalImage = BandMergeDescriptor.create(finalImage, alpha, null);
The problem I have now is that everytime I add an overlay the image changes colors. All the colors become nuances of red or pink. When I add a second overlay, the image becomes normal again, but the first overlay changes colors. All black areas become white.
Also the background of the overlay is not transparent. It is grey.
Below are examples of the images, so you see how the change colors:
As you can see, the picture and overlays change colors and the background of the overlay isn't transparent.
Can you help me solve this problem, so that the image is always displayed correctly? Thanks!
You can try to create a new BufferedImage with ARGB-model, and just paint the non-transparent background picture into this new BufferedImage. Then you have a BufferedImage with alpha-channel (although all of the pixels are opaque), so the Composition should hopefully work.
im not sure about TYPE_4BYTE_ARGB as I usually work with BufferedImages of TYPE_INT_ARGB but I have often used the method of drawing a RGB BufferedImage to a new ARGB BufferedImage and then drawing that onto other things without problem. the change in color would suggest an unwanted change is being made to the other channels in the overlay process as it doesn't seem to be specific to a specific image. If your overlay operation is similar to drawing one image onto another with alpha I would probably suggest using the Graphics.drawImage()/drawRenderedImage() method for the overlay itself not to mention the background should not even need alpha in this case.
the code:
public RenderedImage overlay(RenderedImage back, RenderedImage front, AffineTransform overlayTransformation)
{
BufferedImage newBack = new BufferedImage(back.getWidth(), back.getHeight(), TYPE_3BYTE_RGB);
newBack.setData(back.getData());
Graphics2D graphics = (Graphics2D)(newBack.getGraphics());
graphics.drawRenderedImage(front, overlayTransformation);
return newBack;
}
you may want to ensure the original back Raster is not modified though.
I'm trying to put corners im my ImageView and I find these "workarounds":
1 - Take the Bitmap soure and paint then
2 - put a second ImageView on my layout and use shape+corners as its source
It's not possible take the image view and put a corner around then?
In my app i have a List with a lot of ImageView (the Bitmap used in this ImageView's is programmatically) and I want to put corners in every ImageView.
There is any other option?
You can create a selector that contains shape with rounded corners, and then apply it as the ImageView's background using xml.
Look at this answers here
You can also do it via code by using PorterDuffXfermode. PorterDuffXfermode uses alpha compositing that will allow you to create and intersection (things of mathematical sets here) between the Canvas you get from onDraw() and an off screen Canvas you will have to create. You will use one of the PorterDuff.Mode flags to tell the framework you want to only render the pixels that intersect from the two Bitmaps in each Canvas.
More on Alpha Compositing
I want to paint a Bitmap scaled in a canvas (based on the Bitmap and the View size). The problem is that if I scale the canvas before painting the bitmap:
canvas.scale(1.5f,1.5f);
canvas.drawBitmap(mBitmap, 0, 0, paint);
This is the result:
But if instead of scaling the canvas I scale the bitmap:
Bitmap scaled = Bitmap.createScaledBitmap(
mBitmap, bitmapWidth, bitmapHeight,
true);
canvas.drawBitmap(scaledBitmap, 0, 0, paint);
The result is much better:
The problem is that the Bitmap is pretty big and having in memory both the original and the scaled bitmap may be problematic.
Is there any way to obtain the second result without creating a scaled Bitmap every time the Bitmap or the View bounds changes?
Use a matrix that contains the scaling info when drawing to canvas
canvas.drawBitmap(x,y,..., matrix...)
Use inSampleSize in BitmapOptions when reading the bitmap from your source to scale it accordingly (it is passed as an extra parameter).
This is androids preferred way of loading images in nearly all cases to avoid memory overflow, as the full image is Never loaded into memory.
The android docs on Loading BItmaps efficiently can be found here.
With example code on how to retrieve an image of desired size from your source. (resource, file, etc etc)
The two methods in Loading Large Bitmaps Efficiently are the ones you are looking for.
The solution to my problem was that the Paint hasn't enabled the FILTER_BITMAP_FLAG flag.