Populate a blank bitmap with pixels from another bitmap in Android? - java

I want to create a blank bitmap, which I will conditionally fill with Rects of pixels obtained from another bitmap that holds a resource. Is it possible to do that? How would I go about doing something like that?
I only want to draw the bitmap once it is ready to be drawn.
Right now I'm using Canvas to draw the bitmap using Rect segments, but I don't need it to be drawn until it is ready.
Thanks!

Bitmap other = ...;
//create a blank bitmap
Bitmap newBitmap = Bitmap.createBitmap(other.getWidth(),
other.getHeight(), other.getConfig());
//copy some pixels from 'other'
int x=14,y=45,width=23,height=56;
int [] pixels = new int[width * height];
other.getPixels(pixels, 0, width, x, y, width, height);
newBitmap.setPixels(pixels, 0, width, x, y, width, height);

Related

Increase bitmap size without scaling image

I would like to increase the size of a Bitmap in my Android application.
It sounds like a very simple operation but I cannot find how to do so anywhere.
Here is an image to illustrate what I am trying to achieve here:
Basically, I'd like to create a new bitmap that has the same width as the original, but a bigger height. The background of the (new) extra pixels can be black, white or transparent.
How can I do this?
Some like this should do.
// Create a Canvas to draw to
Canvas bitmapCanvas = new Canvas();
// Create a Bitmap to back the Canvas of the new size
Bitmap bitmap = Bitmap.createBitmap(X, Z, Bitmap.Config.ARGB_8888);
bitmapCanvas.setBitmap(bitmap);
// Calculate the new position of bitmap
// Middle of new Z dimension minus half the original height to centre it.
int newY = (Z / 2) - (Y / 2);
// Draw original bitmap to new location
Paint paint = new Paint();
paint.setAntiAlias(true);
bitmapCanvas.drawBitmap(origBitmap, 0, newY, paint);

How to add stroke/border to transparent png image in android?

I have transparent images like shapes,letters which I'm fetch from gallery so I need to give them stroke/outline with black color, I can set border but It's set to whole bitmap like left,right,top and bottom.
Same thing we can do with photoshop is giving outerstroke to image but I want to achieve that in android.
I tried this and this It's give border, But what I want to do is like below
sample image
Original Image
I want like this -->
Does this possible in android?
I have an temporary solution like this
int strokeWidth = 8;
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_icon);
Bitmap newStrokedBitmap = Bitmap.createBitmap(originalBitmap.getWidth() + 2 * strokeWidth, originalBitmap.getHeight() + 2 * strokeWidth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newStrokedBitmap);
float scaleX = newStrokedBitmap.getWidth() / originalBitmap.getWidth();
float scaleY = newStrokedBitmap.getHeight() / originalBitmap.getHeight();
Matrix matrix = new Matrix();
matrix.setScale(scaleX, scaleY);
canvas.drawBitmap(originalBitmap, matrix, null);
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_ATOP); //Color.WHITE is stroke color
canvas.drawBitmap(originalBitmap, strokeWidth, strokeWidth, null);
Firstly create a new bitmap with stroke size on left, right, bottom and top.
Secondly a little bit scale bitmap and draw scaled bitmap on newly created bitmap canvas.
Draw a color (your stroke color) with PorterDuff mode SRC_ATOP override original bitmap position with stroke color.
Finally draw your original bitmap on newly create bitmap canvas.

Is there a way to scale an image down to a specific size?

I am currently trying to get some kind of 2D dungeoncrawler (think: roguelike) running. Now I want to work with square tiles (32x32) but I wonder if there's a way to make my textures in a higher resolution, say 64x64, and scale them down onto a 32x32 square?
I imagine there has to be since almost all games do this in one way or another but all I can seem to find online is about 3D stuff.
Yeah. When you draw an image, you can add the new width and height to it to resize it.
public static BufferedImage resizeImage(BufferedImage image, int newwidth, int newheight) {
BufferedImage image2 = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_ARGB);
Graphics g = image2.getGraphics();
g.drawImage(image, 0, 0, newwidth, newheight, null);
g.dispose();
return image2;
}
Refer to here for more info.

How to manipulate BufferedImage

Processing has a class named PImage from which you can get an array of int that contains values for all pixels. Then, you manipulate this array and call updatePixels() and voila you have applied an effect to the image.
I was wondering if the same can be done in BufferedImage with some appropriate mechanism. I found that BufferedImage does indeed have a method to get pixels as int[]:
public int[] getRGB(int startX,
int startY,
int w,
int h,
int[] rgbArray,
int offset,
int scansize)
Returns an array of integer pixels in the default RGB color model (`TYPE_INT_ARGB`) and default sRGB color space, from a portion of the image data.
Color conversion takes place if the default model does not match the image `ColorModel`.
There are only 8-bits of precision for each color component in the returned data when using this method.
How do I modify these pixels and show the appropriate changes in BufferedImage ?
I guess I will need to obtain a WritableRaster for the image and use
public void setPixels(int x,
int y,
int w,
int h,
int[] iArray)
but I am still unsure.
To create a WritableRaster, you have to choose a ColorModel first.
I think the RGB default should suit your needs.
ColorModel colorModel = ColorModel.getRGBdefault();
WritableRaster raster = colorModel.createCompatibleWritableRaster(width, height);
Then, you can fill it with your pixels and create a new BufferedImage.
raster.setPixels(0, 0, width, height, pixels);
BufferedImage image = new BufferedImage(colorModel, raster, true, null);
And just as a reminder, here is a way to extract pixels from a BufferedImage:
Raster raster = bufferedImage.getRaster();
int[] pixels = raster.getPixels(0, 0, raster.getWidth(), raster.getHeight(), (int[]) null);
The PImage class integrates a bit with the BufferedImage class:
//BufferedImage to PImage
PImage img = new PImage(yourBufferedImageInstance);
//PImage to BufferedImage
BufferedImage img = (BufferedImage)yourPImageInstance.getNative();

Draw a scaled Bitmap to the Canvas?

The following code defines my Bitmap:
Resources res = context.getResources();
mBackground = BitmapFactory.decodeResource(res, R.drawable.background);
// scale bitmap
int h = 800; // height in pixels
int w = 480; // width in pixels
// Make sure w and h are in the correct order
Bitmap scaled = Bitmap.createScaledBitmap(mBackground, w, h, true);
... And the following code is used to execute/draw it (the unscaled Bitmap):
canvas.drawBitmap(mBackground, 0, 0, null);
My question is, how might I set it to draw the scaled Bitmap returned in the form of Bitmap scaled, and not the original?
Define a new class member variable:
Bitmap mScaledBackground;
Then, assign your newly created scaled bitmap to it:
mScaledBackground = scaled;
Then, call in your draw method:
canvas.drawBitmap(mScaledBackground, 0, 0, null);
Note that it is not a good idea to hard-code screen size in the way you did in your snippet above. Better would be to fetch your device screen size in the following way:
int width = getWindowManager().getDefaultDisplay().getWidth();
int height = getWindowManager().getDefaultDisplay().getHeight();
And it would be probably better not to declare a new bitmap for the only purpose of drawing your original background in a scaled way. Bitmaps consume a lot of precious resources, and usually a phone is limited to a few MB of Bitmaps you can load before your app ungracefully fails. Instead you could do something like this:
Rect src = new Rect(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
Rect dest = new Rect(0, 0, width - 1, height - 1);
canvas.drawBitmap(mBackground, src, dest, null);
To draw the scaled bitmap you want save your scaled bitmap in a field somewhere (here called mScaled) and call:
canvas.drawBitmap(mScaled, 0, 0, null);
in your draw method (or wherever you call it right now).

Categories

Resources