How to rotate bitmap around center point using canvas? - java

I have a bitmap and I want to create a new bitmap obtained by the first rotated around its center. Actually I use this code but it does not work.
Bitmap source = ((BitmapDrawable)r.getDrawable(R.drawable.rectangle)).getBitmap();
int targetWidth = (int)(mWidth * Math.sin(rotationAngle) + mHeight * Math.cos(rotationAngle));
int targetHeight = (int)(mWidth * Math.cos(rotationAngle) + mHeight * Math.sin(rotationAngle));
Bitmap target = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(target);
Matrix m = new Matrix();
m.setRotate(rotationAngle, targetWidth/2f, targetHeight/2f);
c.drawBitmap(source, m, null);
I also tried this code but it doesn't help.
Bitmap source = ((BitmapDrawable)r.getDrawable(R.drawable.rectangle)).getBitmap();
int targetWidth = (int)(mWidth * Math.sin(rotationAngle) + mHeight * Math.cos(rotationAngle));
int targetHeight = (int)(mWidth * Math.cos(rotationAngle) + mHeight * Math.sin(rotationAngle));
Bitmap target = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(target);
c.rotate(rotationAngle, targetWidth/2f, targetHeight/2f);
c.drawBitmap(temp, 0, 0, null);
In this case the rotate command(but the same happens with the scale command) called on the canvas is completely ignored for any parameter. I also tried to use:
c.drawColor(Color.BLACK)
instead of
c.drawBitmap(temp, 0, 0, null);
to paint all the canvas and it confirms that the commands are ignored.

Try this:
Canvas c = new Canvas(target);
c.rotate(rotationAngle, centerX, centerY);
c.drawBitmap(source, null);
Hope this helps :)

int count = canvas.save();
canvas.rotate(rotationAngle, centerX, centerY);
c.drawBitmap(source, null);
canvas.restoreToCount(count);

Related

Java barcode generator [duplicate]

I want to add a string on bitmap image.I have a metod drawTextToBitmap,this method working success place string on bitmap image.But my bitmap image is very small like pinmark image.This function set the string based on the bitmap height and width.I want to place the string exceed than the bitmap image.So Please help me to solve the problem.
Following method i am using to get bitmap :
public Bitmap drawTextToBitmap(Context gContext, int gResId, String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.BLACK);
// text size in pixels
paint.setTextSize((int) (70 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.BLACK);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int m = (bitmap.getWidth() - bounds.width()) / 2;
int l = (bitmap.getHeight() + bounds.height()) / 2;
canvas.drawText(gText, 1000, l, paint);
return bitmap;
}
Try this:
public static Bitmap drawStringonBitmap(Bitmap src, String string, Point location, int color, int alpha, int size, boolean underline,int width ,int height) {
Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
paint.setColor(color);
paint.setAlpha(alpha);
paint.setTextSize(size);
paint.setAntiAlias(true);
paint.setUnderlineText(underline);
canvas.drawText(string, location.x, location.y, paint);
return result;
}

Kaleidoscope Effect in Android

I'm trying to create a Kaleidoscope with an ImageView in Android. I'm struggling to get the rotation and mirroring for each 'segment' correct. I'm new to image manipulation and I'm trying to adapt the code example from here for android.
I have the following code:
private void drawKaleidoscope() {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.cropped_landscape);
Bitmap imageview_bitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
Bitmap matrix_bitmap;
BitmapShader fillShader;
Path triangle_mask = new Path();
RectF r = new RectF(0, 0, bm.getWidth(), bm.getHeight()); // create new rectangle to match the dimensions of our image
this.radius = (int)r.height() / 2;
Canvas c = new Canvas(imageview_bitmap);
c.drawColor(Color.BLACK);
float start_angle = 0;
for (int i = 0; i < this.segments; i++) {
// Create pie-slice shape mask
triangle_mask.reset();
triangle_mask.moveTo(r.centerX(), r.centerY());
triangle_mask.arcTo(r, start_angle, angle);
triangle_mask.close();
// Use odd even check to decide when to mirror the image or not
if (i % 2 == 0) {
Matrix mat = new Matrix();
mat.preTranslate(-radius, -radius);
mat.postRotate(i * angle);
mat.postTranslate(radius, radius);
matrix_bitmap = Bitmap.createBitmap(bm, 0, 0, (int)r.width(), (int)r.height(), mat, true);
}
else {
Matrix mat = new Matrix();
// mirror on x axis
mat.postScale(-1, 1);
mat.postTranslate(-radius, radius);
mat.postRotate((float)-Math.PI);
mat.postRotate(i * angle);
mat.postTranslate(radius, -radius);
matrix_bitmap = Bitmap.createBitmap(bm, 0, 0, (int)r.width(), (int)r.height(), mat, true);
}
fillShader = new BitmapShader(matrix_bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
// Fill the triangle masked area with our image now
Paint fill = new Paint();
fill.setColor(0xFFFFFFFF);
fill.setStyle(Paint.Style.FILL);
fill.setShader(fillShader);
c.drawPath(triangle_mask, fill);
start_angle += angle;
}
kal.setImageBitmap(imageview_bitmap);
}
The output of the above function looks like so:
If anyone could provide some insight on how to properly do the image rotations/mirroring that would be greatly appreciated.
Okay I ended up going about this a different way. Instead of rotating the source image I simply draw the image mask to the same spot on the canvas, and then rotate the canvas itself. Let's say I have 12 image 'slices'. I draw 6 alternating segments, flip the canvas via canvas.scale(-1, 1) and then draw another 6 segments in where the blank spaces are. Here's the code I ended up with:
private Bitmap generateKaleidoscopeBitmap(float start_angle) {
Canvas canvas = new Canvas(imageview_bitmap);
canvas.drawColor(Color.BLACK);
BitmapShader fillShader;
Path triangle_mask = new Path();
RectF r = new RectF(0, 0, imageview_bitmap.getWidth(), imageview_bitmap.getHeight()); // create new rectangle to match the dimensions of our image
int centerX = imageview_bitmap.getWidth() / 2;
int centerY = imageview_bitmap.getHeight() / 2;
// how much to rotate the canvas by after the image is flipped
float offset = calculateCanvasSymmetryOffset(start_angle);
// Create a pie-slice shaped clipping mask
triangle_mask.moveTo(r.centerX(), r.centerY());
triangle_mask.arcTo(r, start_angle, angle);
triangle_mask.close();
// Fill the triangle masked area with our shader now
Paint fill = new Paint();
fill.setColor(0xFFFFFFFF);
fill.setStyle(Paint.Style.FILL);
fillShader = new BitmapShader(source_image, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
fill.setShader(fillShader);
// Rotate the canvas and draw the clipping mask to the canvas
for (int i = 0; i < this.segments / 2; i++) {
canvas.drawPath(triangle_mask, fill);
canvas.rotate(angle * 2, centerX, centerY);
}
// mirror the canvas and rotate it once to counter the symmetrical offset
canvas.scale(-1, 1, centerX, centerY);
canvas.rotate(offset, centerX, centerY);
// Rotate the now mirrored canvas and draw the clipping mask to it
// This is a cheap and easy way of creating mirrored segments
for (int i = 0; i < this.segments / 2; i++) {
canvas.drawPath(triangle_mask, fill);
canvas.rotate(angle * 2, centerX, centerY);
}
return imageview_bitmap;
}

canvas.drawBitmap bad Location and size (not placing image correctly)

Hi everyone and beforehand thanks, I hope are well write because I am doing a simple application that should unite more than two bitmaps in only one, the problem is in which position bitmaps and size Side wrong, and the truth will not find the back for logic given to me that 's fine, in fact it is a Tengo Que code already in c # and PASE java obviously is different sin but have the same principle .
I wonder if you have the way to make the position and size of these images out as this saying in the code,
Sorry for my bad English
CODIGO JAVA
Paint mPaint;
Bitmap image1=BitmapUtils.decodeBase64(Lie.GeFondo().GetImagen());
Bitmap image2=BitmapUtils.decodeBase64(Utilidades.getImagenTomadabase64());
Bitmap image3=BitmapUtils.decodeBase64(Lie.GetBanner().GetImagen());
Bitmap result = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect srcRect = new Rect(0, 0, image1.getWidth(), image1.getHeight());
Rect dstRect = new Rect(srcRect);
Rect srcRect1 = new Rect( Foto.GetPosicionDeItems().Getx(),Foto.GetPosicionDeItems().Gety(),Foto.GetTamano().GetWidth(), Foto.GetTamano().GeHeight());
Rect srcRect3 = new Rect( Lie.GetBanner().GetPosicionDeItems().Getx(), Lie.GetBanner().GetPosicionDeItems().Gety() ,Lie.GetBanner().GetTamano().GetWidth(), Lie.GetBanner().GetTamano().GeHeight());
Rect srcRect2 = new Rect(0,0,image2.getWidth(), image2.getHeight());
Rect srcRect4 = new Rect(0,0,image3.getWidth(), image3.getHeight());
dstRect.offset(0, 0);
canvas.drawBitmap(image1, srcRect, dstRect, null);
dstRect.offset(image1.getWidth(), 0);
srcRect1.offset(0, 0);
canvas.drawBitmap(image2,srcRect2 ,srcRect1 , null);
srcRect1.offset(image2.getWidth(), 0);
srcRect3.offset(0, 0);
canvas.drawBitmap(image3,srcRect4 ,srcRect3 , null);
srcRect3.offset(image3.getWidth(), 0);
myImage = (ImageView) findViewById(R.id.imageView);
myImage.setImageBitmap(result);
in Java
see java picture http://i58.tinypic.com/1zywm5u.jpg
C# Code
Ignore the foreach.
System.Drawing.Bitmap Bac = (System.Drawing.Bitmap)Lienzo.Fondo.Imagen;
System.Drawing.Graphics r = System.Drawing.Graphics.FromImage(Bac);
if (Lienzo.Fotos != null)
{
if (Lienzo.Fotos.Count > 0)
{
int i = 0;
foreach (RADMLIB.Items item in Lienzo.Fotos)
{
System.Drawing.Bitmap img = (System.Drawing.Bitmap)Lista[i];
r.DrawImage(img, item.PosicionDeItems.X, item.PosicionDeItems.Y, item.Tamano.Width, item.Tamano.Height);
i++;
}
}
}
if (Lienzo.Banner != null)
{
r.DrawImage((System.Drawing.Bitmap)Lienzo.Banner.Imagen, Lienzo.Banner.PosicionDeItems.X, Lienzo.Banner.PosicionDeItems.Y, Lienzo.Banner.Tamano.Width, Lienzo.Banner.Tamano.Height);
}
return Bac;
see c# picture http://i61.tinypic.com/s61wlh.jpg
I found the solution
using Matrix for set location and scale x,y
Bitmap image1=BitmapUtils.decodeBase64(Lie.GeFondo().GetImagen());
Bitmap image2=BitmapUtils.getResizedBitmap(BitmapUtils.decodeBase64(Utilidades.getImagenTomadabase64()),Foto.GetTamano().GetWidth(),Foto.GetTamano().GeHeight());
Bitmap image3=BitmapUtils.getResizedBitmap(BitmapUtils.decodeBase64(Lie.GetBanner().GetImagen()),Lie.GetBanner().GetTamano().GetWidth(),Lie.GetBanner().GetTamano().GeHeight());
Bitmap result = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);//Create the canvas to your image
Rect srcRect = new Rect(0, 0, image1.getWidth(), image1.getHeight());
Rect dstRect = new Rect(srcRect);
Matrix matrix = new Matrix ();
Matrix matrix2 = new Matrix ();
matrix.postTranslate( Foto.GetPosicionDeItems().Getx(),Foto.GetPosicionDeItems().Gety());
matrix2.postTranslate( Lie.GetBanner().GetPosicionDeItems().Getx(),Lie.GetBanner().GetPosicionDeItems().Gety());
canvas.drawBitmap(image1, srcRect, dstRect, null);
dstRect.offset(image1.getWidth(), 0);
canvas.drawBitmap(image2,matrix , null);
canvas.drawBitmap(image3,matrix2 , null);
getResizedBitmap Method
public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
see the image
https://lh4.ggpht.com/LXW8kVc3U8qQUHnORI-3H4H-A2hjq92y_oEDsKIs-iBDkVBFTgjGP03xFReCeuyLlg=h900-rw

Rotate a saved bitmap in android

I am saving an image from the camera that was in landscape mode. so it gets saved in landscape mode and then i apply an overlay onto it that too is in landscape mode. I want to rotate that image and then save. e.g. if i have this
I want to rotate clockwise by 90 degrees once and make it this and save it to sdcard:
How is this to be accomplished?
void rotate(float x)
{
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.tedd);
int width = bitmapOrg.getWidth();
int height = bitmapOrg.getHeight();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
matrix.postRotate(x);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,width, height, matrix, true);
iv.setScaleType(ScaleType.CENTER);
iv.setImageBitmap(resizedBitmap);
}
Check this
public static Bitmap rotateImage(Bitmap src, float degree)
{
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
Bitmap bmp = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return bmp;
}
You can use the Canvas API to do that. Note that you need to switch width and height.
final int width = landscapeBitmap.getWidth();
final int height = landscapeBitmap.getHeight();
Bitmap portraitBitmap = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(portraitBitmap);
c.rotate(90, height/2, width/2);
c.drawBitmap(landscapeBitmap, 0,0,null);
portraitBitmap.compress(CompressFormat.JPEG, 100, stream);
Use a Matrix.rotate(degrees) and draw the Bitmap to it's own Canvas using that rotating matrix. I don't know though if you might have to make a copy of the bitmap before drawing.
Use Bitmap.compress(...) to compress your bitmap to an outputstream.
The solution of Singhak works fine.
In case you need fit the size of result bitmap (perhaps for ImageView) you can expand the method as follows:
public static Bitmap rotateBitmapZoom(Bitmap bmOrg, float degree, float zoom){
Matrix matrix = new Matrix();
matrix.postRotate(degree);
float newHeight = bmOrg.getHeight() * zoom;
float newWidth = bmOrg.getWidth() / 100 * (100.0f / bmOrg.getHeight() * newHeight);
return Bitmap.createBitmap(bmOrg, 0, 0, (int)newWidth, (int)newHeight, matrix, true);
}

How to change a bitmap's opacity?

I have a bitmap:
Bitmap bitmap = BitmapFactory.decodeFile("some/arbitrary/path/image.jpg");
But I'm not going to display the image to the user. I want the alpha to be 100 (out of 255). If this is not possible, can I set the opacity of the Bitmap?
As far as I know, opacity or other color filters can't be set on the Bitmap itself. You will need to set the alpha when you use the image:
If you're using ImageView, there is ImageView.setAlpha().
If you're using a Canvas, then you need to use Paint.setAlpha():
Paint paint = new Paint();
paint.setAlpha(100);
canvas.drawBitmap(bitmap, src, dst, paint);
Also, incorporating WarrenFaith's answer, if you will use the Bitmap where a drawable is required, you can use BitmapDrawable.setAlpha().
You could also try BitmapDrawable instead of Bitmap. If this is useful for you depends on the way you use the bitmap...
Edit
As a commenter asked how he can store the bitmap with alpha, here is some code:
// lets create a new empty bitmap
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
// create a canvas where we can draw on
Canvas canvas = new Canvas(newBitmap);
// create a paint instance with alpha
Paint alphaPaint = new Paint();
alphaPaint.setAlpha(42);
// now lets draw using alphaPaint instance
canvas.drawBitmap(originalBitmap, 0, 0, alphaPaint);
// now lets store the bitmap to a file - the canvas has drawn on the newBitmap, so we can just store that one
// please add stream handling with try/catch blocks
FileOutputStream fos = new FileOutputStream(new File("/awesome/path/to/bitmap.png"));
newBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
public Bitmap makeTransparent(Bitmap src, int value) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap transBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(transBitmap);
canvas.drawARGB(0, 0, 0, 0);
// config paint
final Paint paint = new Paint();
paint.setAlpha(value);
canvas.drawBitmap(src, 0, 0, paint);
return transBitmap;
}
Bitmap bgr = BitmapFactory.decodeResource(getResources(),R.drawable.main_logo_2);
Paint transparentpainthack = new Paint();
transparentpainthack.setAlpha(100);
canvas.drawBitmap(bgr, 0, 0, transparentpainthack);
https://dzone.com/articles/adjusting-opacity-android proposes:
/**
* #param bitmap The source bitmap.
* #param opacity a value between 0 (completely transparent) and 255 (completely
* opaque).
* #return The opacity-adjusted bitmap. If the source bitmap is mutable it will be
* adjusted and returned, otherwise a new bitmap is created.
*/
private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
{
Bitmap mutableBitmap = bitmap.isMutable()
? bitmap
: bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
int colour = (opacity & 0xFF) << 24;
canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
return mutableBitmap;
}
Note that with DST_IN you can modify (rather than reset) the transparency of already transparent image, that is, you can make the image more and more transparent.
If you are using a Drawable to display the image, you can change the alpha as follows:
private Drawable mTriangle;
mTriangle = context.getResources().getDrawable(R.drawable.triangle_arrow_for_radar);
...
protected void onDraw(Canvas canvas)
{
// Draw the triangle arrow
float imageTargetWidth = getWidth() / 15;
float scale = mTriangle.getIntrinsicWidth() / imageTargetWidth;
int imgWidth = (int)(imageTargetWidth);
int imgHeight = (int)(mTriangle.getIntrinsicHeight() / scale);
if (mTriangle != null)
{
mTriangle.setBounds(getWidth() / 2 - imgWidth / 2, getHeight() / 2 - imgHeight / 2, getWidth() / 2 + imgWidth / 2, getHeight() / 2 + imgHeight / 2);
mTriangle.setAlpha(150); // from (transparent) to 255 (opaque)
mTriangle.draw(canvas);
}
}

Categories