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);
Related
i want to creat an android app
that shows all pixels of an image but when i zoom color of the corners of the pixels blend with other pixels around it i want pixels to show their color perfectly in their squares
( like pixel art or ms paint when you zoom it)
i tried drawing a rectangle on canvas and drawing a bitmap 1×1
with color what i want but it blends
here is a picture and code
upper pic 4×4 what it creates
lower pic what i want
try{
//creating bitmap from other for background
bt2 = Bitmap.createBitmap(bt,i2,i3,i,i);
}
Canvas c=new Canvas(bt2);
c.drawColor(Color.argb(255,255,255,255));
//creating 1×1 image
Bitmap bt3 = Bitmap.createBitmap(bt,0,0,1, 1 );
//blue color to draw for pixel looking
Canvas c2 =new Canvas(bt3);
c2.drawColor(Color.argb(255,0,0,255));
int w=bt2.getWidth();
int h= bt2.getHeight();
//geting pixels so i would use it
btpixels=new int [w*h];
bt2.getPixels(btpixels,
0,w,0,0,w,h );
int j =0;
Paint paint =new Paint();
for(j=0;j<w;j++)
{
paint.setARGB(255,0,255,0);
//drawing blue bitmap on bt2
c.drawBitmap(bt3,j,j,paint) ;
//paint.setColor( btpixels[j]);
/* c.drawRect(
(float)i-1,
(float) i-1,
(float)i,
(float)i,
paint ); */
}
img.setImageBitmap( bt2 );
}catch(IllegalArgumentException e){ }
i understood how to stop pixels from blending. I was using 2×2 image on the screen 300ppi . If i want to show 1 pixel per inch i should use pixel bitmap(here bt3) width as 300
best would be
width of the pixel square =
width of the screen / num of pixels
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.
I have implemented a flood fill algorithm in an android app. The way I have implemented the algorithm doesn't actually change the source bitmap, but instead creates a new bitmap of the fill area. I.E.
Flood filling this circle with red
Would produce this bitmap (where everything else in the bitmap is transparent)
Which I then combine again into a single bitmap. This works great for solid colors, but I want to be able to implement a gradient flood fill so that if a user fills the same circle, choosing red and blue, the resulting bitmap would look like this
My question is, is there a way that I can use the red circle as some sort of mask to make the desired gradient? or do I have to write a gradient generator myself?
Thanks to pskink's hint, I was able to find an answer.
The idea is that you create a canvas, draw the mask to it, create the gradient that you want, then draw the gradient on top of it using the SRC_IN PorterDuffXfermode. Here's the code:
public Bitmap addGradient(Bitmap src, int color1, int color2)
{
int w = src.getWidth();
int h = src.getHeight();
Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,0,0,h, color1, color2, Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawRect(0,0,w,h,paint);
return result;
}
In this instance, the DST(destination) is the red circle and the SRC(source) is the gradient. The SRC_IN PorterDuff mode means draw the SRC everywhere that it intersects with the DST.
Note that it really doesn't matter what color the mask is, because the PorterDuff mode only pays attention to whether the DST pixel is transparent or not. The color of the resulting bitmap will be a gradient between color1 and color2.
I simply want to rotate an image from min to max. But for that i have used multiple images to show Progress. Can some one suggest me a way to use a single image. which can rotate at an angle from min to max.
I know there are two possible ways to achieve it.
Using Animation Classes
Custom View
I simply want to rotate this image using SeekBar in any number of steps.
How can i achieve this?
To roate an Image
private void rotate(float degree) {
final RotateAnimation rotateAnim = new RotateAnimation(0.0f, degree,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(0);
rotateAnim.setFillAfter(true);
imgview.startAnimation(rotateAnim);
}
Second Approach
imageView.setRotation(angle); // but requires API >= 11
I can use Matrix
Matrix matrix = new Matrix();
imageView.setScaleType(ScaleType.MATRIX); //required
matrix.postRotate((float) angle, pivX, pivY);
imageView.setImageMatrix(matrix);
How can i set Start and end angle to SeekBar min and max respectively. Which approach is better and Whether i must put it in FrameLayout to let it rotate freely.
You can do this way :
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// rotate the Bitmap
matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
For details check this out.
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html
matrix.postRotate(45); //here 45 is the degree of angle to rotate
You can use a Matrix as suggested here
Matrix matrix = new Matrix();
imageView.setScaleType(ScaleType.MATRIX); //required
matrix.postRotate((float) angle, pivX, pivY);
imageView.setImageMatrix(matrix);
This would be an infinite rotation but you could spin it however you want.
This view just spins 360 degrees infinitely.
final RotateAnimation R = new RotateAnimation(0, 360, view.getWidth() / 2.0f, view.getHeight() / 2.0f);
R.setRepeatCount(Animation.INFINITE);
R.setDuration(800);
view.startAnimation(R);
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).