Rotate an imageView at an angle using Seekbar - java

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);

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 create a bitmap whose dimension is the central square of the screen?

Context & Goal
I'm building a real-time object detection app. To achieve this, I need a bitmap to send to the recognition algorithm. I have an activity displaying the camera output in full screen, but I'm trying to operate the recognition only on the central square of the screen. So I need a bitmap with those dimensions and position, corresponding to the the central square of the phone screen.
What I have tried
#Override
public void onPreviewSizeChosen(final Size size, final int rotation) {
/* some code... */
// Width of the screen (larger than the height), for my phone it's 4032
previewWidth = size.getWidth();
// Height of the screen, for my phone it's 1980
previewHeight = size.getHeight();
sensorOrientation = rotation - getScreenOrientation();
// The bitmap which will be used to the recognition, dimension : full screen of the phone
rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
// squared bitmap 320x320, required size for the recognition algorithm
croppedBitmap = Bitmap.createBitmap(cropSize, cropSize, Config.ARGB_8888);
// bitmap to croppedBitmap transform Matrix
frameToCropTransform =
ImageUtils.getTransformationMatrix(
previewWidth, previewHeight,
cropSize, cropSize,
sensorOrientation, MAINTAIN_ASPECT);
cropToFrameTransform = new Matrix();
frameToCropTransform.invert(cropToFrameTransform);
trackingOverlay = (OverlayView) findViewById(R.id.tracking_overlay);
trackingOverlay.addCallback(
new DrawCallback() {
#Override
public void drawCallback(final Canvas canvas) {
tracker.draw(canvas, isDebug());
}
});
tracker.setFrameConfiguration(previewWidth, previewHeight, sensorOrientation);
}
#Override
protected void processImage() {
trackingOverlay.postInvalidate();
if (computingDetection) {
readyForNextImage();
return;
}
computingDetection = true;
// THE LINE I CAN'T FIGURE OUT
// I try to set width and height = previewHeight (1980 for my phone so a square)
// and to move it down by (previewWidth-previewHeight)/2 so it goes in the middle of the screen
rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, (previewWidth-previewHeight)/2, previewHeight, previewHeight);
readyForNextImage();
final Canvas canvas = new Canvas(croppedBitmap);
canvas.drawBitmap(rgbFrameBitmap, frameToCropTransform, null);
// Saved set to true, so I can check what the bitmap sent to the recognition algorithm looks like
if (SAVE_PREVIEW_BITMAP) {
ImageUtils.saveBitmap(croppedBitmap);
}
runInBackground(
new Runnable() {
#Override
public void run() {
// Here we send the bitmap to the recognition algorithm to perform real-time detection
final List<Classifier.Recognition> results = detector.recognizeImage(croppedBitmap);
/* some code ... */
}
If I replace the (previewWidth-previewHeight)/2 by 0 as the y parameter of rgbFrameBitmap.setPixels() function, I manage to perform real-time recognition in a square on top of the screen, as I want unless it's not centered. But as soon as I set the y parameter to (previewWidth-previewHeight)/2, this is the error I get when it tries to save the bitmap :
W/ImageReader_JNI: Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
How can I get the bitmap to be centered in the middle of the screen ?
Self solved
There are two thing I misunderstood on the above code.
First, I mixed up the x and the y parameters of the rgbFrameBitmap.setPixels() function, but in any case this was just adding some black space to the bitmap. To obtain the center of the screen, the parameter to change is the offset, like this :
int x = (previewWidth-previewHeight)/2;
rgbFrameBitmap.setPixels(getRgbBytes(), x, previewWidth, 0, 0, previewHeight, previewHeight);
Besides, as we send the croppedBitmap to the recognition algorithm, which is the rgbFrameBitmap cropped to 320x320 thanks to the matrix frameToCropTransform, I had to update this :
frameToCropTransform =
ImageUtils.getTransformationMatrix(
previewWidth, previewHeight,
cropSize, cropSize,
sensorOrientation, MAINTAIN_ASPECT);
into this :
frameToCropTransform =
ImageUtils.getTransformationMatrix(
previewHeight, previewHeight,
cropSize, cropSize,
sensorOrientation, MAINTAIN_ASPECT);
as rgbFrameBitmap is now a square of dimensions previewHeightxpreviewHeight
Horizontal Screen
To get the central square area of a screen, compare height and width of the screen in pixels. Usually for desktop systems width is bigger, and I will assume this is the case.
Get the difference width-height, divide by two and call it x.
Finally draw a rectangle from (x, 0) to (x+height, height).
More General
The side length of the square will be length = min(width,height)
The coordinates of the square will be
x = (width-length)/2
y = (height-length)/2
Finally draw a rectangle from (x, y) to (x+length, y+length).

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.

Rotating a Bitmap around a point NOT center to bitmap

I have a bitmap that I would like to rotate about a point on a canvas. The point I want to rotate it about is not the center of the bitmap. I am using a matrix. Here is an example of what I have.
Bitmap image = ContentManager.getInstance().getImage(imageId);
Matrix matrix = new Matrix();
matrix.setTranslate(-image.getWidth()/2f, -image.getHeight()/2f);
matrix.postRotate(rotationDegrees);
matrix.postTranslate(x / scaleX, y / scaleY);
matrix.postScale(scaleX, scaleY);
paint.setAlpha(alpha);
canvas.drawBitmap(image, matrix, paint);
I want to manipulate this code slightly to not rotate around the bitmap's center point but a different point. To illustrate more clearly I have created this picture:
.
I have tried everything I can think of from setting
matrix.setTranslate(-image.getWidth()/2f, -image.getHeight()/2f);
to
matrix.setTranslate(pivotPoint.x, pivotPoint.y);
and a lot of other stuff. The result is the bitmap is always way off from where I expected it. (eg. rotate it about the center of the screen 90 degrees would put the bitmap 90 degrees from where it was and consequently would be rotated.) The bitmap always seems to rotate about its center point and then ends up in a random spot on the screen.
After much messing around and find this very difficult or buggy, not sure which, found the easiest solution to this is to find the new center of the bitmap and drop the image there instead, seem more complicated but it works where plain rotation/translation wasn't.
float angle;
float radius;
Bitmap wheelSelectBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Matrix matrix = new Matrix();
Point pivotPoint = new Point();
pivotPoint.set(pivotPoint.x, pivotPoint.y)
Point newCenter = new Point();
newCenter.set((int)(pivotPoint.x + (radius * Math.cos(angle)), (int)(pivotPoint.y - (radius * Math.sin(angle)));
matrix.postTranslate(newCenter.x - (bitmap.getWidth()/2f), newCenter.y - (bitmap.getHeight()/2f));
matrix.postRotate(angle, newCenter.x, newCenter.y);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), null, true);
canvas.drawBitmap(bitmap, matrix, null);
This might not be perfect but working this way solved the problem for me and stopped bitmaps flying around all over the shop. It also rotates clockwise by default unlike your diagram so just use -angle for counter-CW. Not sure what is going on here as this code definitely failed to get the desired effect for me:
matrix.postTranslate(pivotPoint.x, pivotPoint.y);
matrix.postRotate(angle);
matrix.postTranslate(radius - (bitmap.getWidth()/2f), -bitmap.getHeight()/2f);
Cant see what is wrong with logic here ? But in my case the bitmap was not visible in the view here.
When rotating an object, it will rotate around the origin (upper left corner). You'll want to first translate the bitmap so the pivot point becomes (0, 0), rotate the bitmap then translate back to it's original position.
you could try something like this:
matrix.setTranslate(-px, -py);
matrix.postRotate(rotationDegrees);
matrix.setTranslate(px, py);
// Then do other things.

Rotated image in ImageView

I want to show an arrow that indicates the direction towards a goal, using the orientation sensor and current GPS position. Everything works well, except that I want to rotate the arrow image in my ImageView.
The current code, which shows the arrow pointing upwards, is this:
ImageViewArrow.setImageResource(R.drawable.arrow);
What is the best solution for showing the arrow, rotated by N degrees?
I tried this, but it gave messed up graphics:
Matrix matrix = new Matrix();
matrix.postRotate(Rotation);
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.arrow);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
bitmapOrg.getWidth(),bitmapOrg.getHeight(), matrix, true);
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
InfoArrow.setScaleType(ScaleType.CENTER);
InfoArrow.setImageDrawable(bmd);
here you can find a tutorial
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html
There is a matrix parameter in the createBitmap method that can be used for resizing and rotating the image. You could try something like the following:
Matrix matrix = new Matrix();
// to rotate the image bitmap use post Rotate
matrix.postRotate(45);
Bitmap rotatedImage = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true); `

Categories

Resources