I am trying to rotate image to some degree and fill background to red color. For example I have a image and want to rotate minute niddle to 15 min(45 degree) and show that quarter circle with red color.
I used following code with rotate my rotate to some angle but i am not able to fill background color. Please help.
RotateAnimation rotateAnimation = new RotateAnimation(
(1 - 1) * 6, 10 * 6,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(5000);
rotateAnimation.setFillEnabled(true);
rotateAnimation.setFillBefore(true);
rotateAnimation.setBackgroundColor(Color.RED);
orgClockImage.startAnimation(rotateAnimation);
Thanks
you can rotate the bitmap with matrix also.
public class RotateBitmap {
public static final String TAG = "RotateBitmap";
private Bitmap mBitmap;
private int mRotation;
private int mWidth;
private int mHeight;
private int mBitmapWidth;
private int mBitmapHeight;
public RotateBitmap( Bitmap bitmap, int rotation )
{
mRotation = rotation % 360;
setBitmap( bitmap );
}
public void setRotation( int rotation )
{
mRotation = rotation;
invalidate();
}
public int getRotation()
{
return mRotation % 360;
}
public Bitmap getBitmap()
{
return mBitmap;
}
public void setBitmap( Bitmap bitmap )
{
mBitmap = bitmap;
if ( mBitmap != null ) {
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
invalidate();
}
}
private void invalidate()
{
Matrix matrix = new Matrix();
int cx = mBitmapWidth / 2;
int cy = mBitmapHeight / 2;
matrix.preTranslate( -cx, -cy );
matrix.postRotate( mRotation );
matrix.postTranslate( cx, cx );
RectF rect = new RectF( 0, 0, mBitmapWidth, mBitmapHeight );
matrix.mapRect( rect );
mWidth = (int)rect.width();
mHeight = (int)rect.height();
}
public Matrix getRotateMatrix()
{
Matrix matrix = new Matrix();
if ( mRotation != 0 ) {
int cx = mBitmapWidth / 2;
int cy = mBitmapHeight / 2;
matrix.preTranslate( -cx, -cy );
matrix.postRotate( mRotation );
matrix.postTranslate( mWidth / 2, mHeight / 2 );
}
return matrix;
}
public int getHeight()
{
return mHeight;
}
public int getWidth()
{
return mWidth;
}
public void recycle()
{
if ( mBitmap != null ) {
mBitmap.recycle();
mBitmap = null;
}
}
}
Related
I'm using KenBurnsView to add animation to my image.
Is it possible to set the max scale programmatically ? Small images are too zooming.
Yes, you can . For this purpose you have to implement your own TransitionGenerator.
Like given blow .In following code you can call SetMinRectFactor() to set minimum zoom sacale.
public class BackgroundTransitionGenerator implements TransitionGenerator
{
private static final int DEFAULT_TRANSITION_DURATION = 9000;
private static final Interpolator DEFAULT_TRANSITION_INTERPOLATOR =
new LinearInterpolator();
private long transitionDuration;
private Interpolator transitionInterpolator;
private Transition lastTransition;
private RectF lastDrawableBounds;
private boolean forward;
private float MIN_RECT_FACTOR=1.0f;
public void SetMinRectFactor(float f)
{
MIN_RECT_FACTOR=f;
}
public BackgroundTransitionGenerator() {
transitionDuration = DEFAULT_TRANSITION_DURATION;
transitionInterpolator = DEFAULT_TRANSITION_INTERPOLATOR;
}
#Override
public Transition generateNextTransition(RectF drawableBounds, RectF viewport) {
float drawableRatio = getRectRatio(drawableBounds);
float viewportRectRatio = getRectRatio(viewport);
RectF startRect;
RectF endRect;
if (drawableRatio >= viewportRectRatio) {
float w = drawableBounds.height() * viewportRectRatio;
float h = drawableBounds.height();
startRect = new RectF(0, 0, w, h);
endRect =generateRandomRect(drawableBounds,viewport); //new RectF((drawableBounds.width() - w), drawableBounds.height(),drawableBounds.width(), h);
} else {
float w = drawableBounds.width();
float h = drawableBounds.width() / viewportRectRatio;
startRect = new RectF(0, 0, w, h);
endRect =generateRandomRect(drawableBounds,viewport); //new RectF(0, drawableBounds.height() - h, w, drawableBounds.height());
}
if (!drawableBounds.equals(lastDrawableBounds) || !haveSameAspectRatio(lastTransition.getDestinyRect(), viewport)) {
forward = false;
}
forward = !forward;
if (forward) {
lastTransition = new Transition(startRect, endRect, transitionDuration, transitionInterpolator);
} else {
lastTransition = new Transition(endRect, startRect, transitionDuration, transitionInterpolator);
}
lastDrawableBounds = new RectF(drawableBounds);
return lastTransition;
}
private static boolean haveSameAspectRatio(RectF r1, RectF r2) {
return (Math.abs(getRectRatio(r1) - getRectRatio(r2)) <= 0.01f);
}
private RectF generateRandomRect(RectF drawableBounds, RectF viewportRect) {
float drawableRatio = getRectRatio(drawableBounds);
float viewportRectRatio = getRectRatio(viewportRect);
RectF maxCrop;
if (drawableRatio > viewportRectRatio) {
float r = (drawableBounds.height() / viewportRect.height()) * viewportRect.width();
float b = drawableBounds.height();
maxCrop = new RectF(0, 0, r, b);
} else {
float r = drawableBounds.width();
float b = (drawableBounds.width() / viewportRect.width()) * viewportRect.height();
maxCrop = new RectF(0, 0, r, b);
}
float factor = MIN_RECT_FACTOR ;
float width = factor * maxCrop.width();
float height = factor * maxCrop.height();
int widthDiff = (int) (drawableBounds.width() - width);
int heightDiff = (int) (drawableBounds.height() - height);
int left = widthDiff;
int top = heightDiff;
return new RectF(left, top, left + width, top + height);
}
private static float getRectRatio(RectF rect) {
return rect.width() / rect.height();
}
}
I do this to get a circular ImageView, how can I add a circle border around it like this picture:
public static Bitmap getRoundedShape(Bitmap scaleBitmapImage,int width) {
int targetWidth = width;
int targetHeight = width;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth),
((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap,
new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()),
new Rect(0, 0, targetWidth, targetHeight), null);
return targetBitmap;
}
There is a very interesting post about this feature:
http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
It is written by Romain Guy (ex android team at Google).
You can use something like this:
This example create a circular bitmap, with around a white stroke.
You can change it, adding a white stroke with a black line.
public class CircleDrawable extends Drawable {
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private Paint mWhitePaint;
int circleCenterX;
int circleCenterY;
int mRadus;
private boolean mUseStroke = false;
private int mStrokePadding = 0;
public CircleDrawable(Bitmap bitmap) {
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
}
public CircleDrawable(Bitmap bitmap, boolean mUseStroke) {
this(bitmap);
if (mUseStroke) {
this.mUseStroke = true;
mStrokePadding = 4;
mWhitePaint = new Paint();
mWhitePaint.setStyle(Paint.Style.FILL_AND_STROKE);
mWhitePaint.setStrokeWidth(0.75f);
mWhitePaint.setColor(Color.WHITE);
}
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
circleCenterX = bounds.width() / 2;
circleCenterY = bounds.height() / 2;
if (bounds.width() >= bounds.height())
mRadus = bounds.width() / 2;
else
mRadus = bounds.height() / 2;
}
#Override
public void draw(Canvas canvas) {
if (mUseStroke) {
canvas.drawCircle(circleCenterX, circleCenterY, mRadus, mWhitePaint);
}
canvas.drawCircle(circleCenterX, circleCenterY, mRadus - mStrokePadding, mPaint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
public boolean ismUseStroke() {
return mUseStroke;
}
public void setmUseStroke(boolean mUseStroke) {
this.mUseStroke = mUseStroke;
}
}
I want implement move a sprite from position (x ,y ) to position action_down (x1 , y1) .But I can't rotate it .Please help me .Thanks
This is my code:
public Sprite(GameView gameView, Bitmap bmp) {
this.gameView = gameView;
this.bmp = bmp;
this.width = bmp.getWidth() / BMP_COLUMNS;// create width, height
this.height = bmp.getHeight() / BMP_ROWS;
Random rnd = new Random(System.currentTimeMillis());
x = rnd.nextInt(gameView.getWidth() - bmp.getWidth());
y = rnd.nextInt(gameView.getHeight() - bmp.getHeight());
}
public void onDraw(Canvas canvas) {
Matrix matrix = new Matrix();
matrix.postTranslate(x, y);
float dx = x1-x;
float dy = y1-y;
float d = (float)Math.sqrt(dx*dx+dy*dy);
vx = (float) (dx*5/d)/3 ;
vy = (float) (dy*5/d)/3 ;
if(k==1){
x += vx ;
y += vy ;
}
currentFrame = ++currentFrame % BMP_COLUMNS;
int srcX = currentFrame * width;
int srcY = 0 * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
You should look at matrix.postRotate or canvas.rotate.
Here you go:
Note: you need to convert from Bitmap to Image.
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
/**
* Created by Chris on 3/28/2014.
*/
public class Sprite {
private Image i;
public Sprite(Image image) {
this.i = image;
}
private BufferedImage image = null;
private Graphics2D graphics = null;
public void onDraw(Canvas canvas) {
if(image == null || graphics == null) {
setup();
}
Graphics g = canvas.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
//Where to draw the Sprite on the canvas.
int x = 100;
int y = 100;
//Because graphics is an instance of Graphics2D
//Converts the degrees "45" to radians.
double rotationAngle = Math.toRadians(45);
double locX = image.getWidth() / 2;
double locY = image.getHeight() / 2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationAngle, locX, locY);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
graphics.drawImage(op.filter(image, null), 0, 0, null);
g.drawImage(image, x, y, (int) (image.getWidth() / 2), (int) (image.getHeight() / 2), null);
}
/**
* Sets the Image up.
*/
private void setup() {
if(image != null) {
image.flush();
image = null;
}
if(graphics != null) {
graphics.dispose();
graphics = null;
}
image = new BufferedImage(i.getWidth(null) * 2, i.getHeight(null) * 2, BufferedImage.TYPE_INT_ARGB);
graphics = image.createGraphics();
}
}
I'm trying to figure out how to wite a simple drawing program in Android. I saw a sample program that stored each stroke in a array, then played back the array when the screen needed to be updated. To me this did not seem to proctical. I would like to draw in a bitmap, and the update would just draw the bitmap instad of every stroke. ( i could not figure out how to do this in android)
Any thoughts
?
Ted
Look at the Android samples: there are a couple of moderately complicated bits, but this is from the Sensors.java api demo in the Android SDK. It demonstrates the bitmap manipulation:
private class GraphView extends View implements SensorEventListener
{
private Bitmap mBitmap;
private Paint mPaint = new Paint();
private Canvas mCanvas = new Canvas();
private Path mPath = new Path();
private RectF mRect = new RectF();
private float mLastValues[] = new float[3*2];
private float mOrientationValues[] = new float[3];
private int mColors[] = new int[3*2];
private float mLastX;
private float mScale[] = new float[2];
private float mYOffset;
private float mMaxX;
private float mSpeed = 1.0f;
private float mWidth;
private float mHeight;
public GraphView(Context context) {
super(context);
mColors[0] = Color.argb(192, 255, 64, 64);
mColors[1] = Color.argb(192, 64, 128, 64);
mColors[2] = Color.argb(192, 64, 64, 255);
mColors[3] = Color.argb(192, 64, 255, 255);
mColors[4] = Color.argb(192, 128, 64, 128);
mColors[5] = Color.argb(192, 255, 255, 64);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mRect.set(-0.5f, -0.5f, 0.5f, 0.5f);
mPath.arcTo(mRect, 0, 180);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
mCanvas.setBitmap(mBitmap);
mCanvas.drawColor(0xFFFFFFFF);
mYOffset = h * 0.5f;
mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
mWidth = w;
mHeight = h;
if (mWidth < mHeight) {
mMaxX = w;
} else {
mMaxX = w-50;
}
mLastX = mMaxX;
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
synchronized (this) {
if (mBitmap != null) {
final Paint paint = mPaint;
final Path path = mPath;
final int outer = 0xFFC0C0C0;
final int inner = 0xFFff7010;
if (mLastX >= mMaxX) {
mLastX = 0;
final Canvas cavas = mCanvas;
final float yoffset = mYOffset;
final float maxx = mMaxX;
final float oneG = SensorManager.STANDARD_GRAVITY * mScale[0];
paint.setColor(0xFFAAAAAA);
cavas.drawColor(0xFFFFFFFF);
cavas.drawLine(0, yoffset, maxx, yoffset, paint);
cavas.drawLine(0, yoffset+oneG, maxx, yoffset+oneG, paint);
cavas.drawLine(0, yoffset-oneG, maxx, yoffset-oneG, paint);
}
canvas.drawBitmap(mBitmap, 0, 0, null);
float[] values = mOrientationValues;
if (mWidth < mHeight) {
float w0 = mWidth * 0.333333f;
float w = w0 - 32;
float x = w0*0.5f;
for (int i=0 ; i<3 ; i++) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(x, w*0.5f + 4.0f);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
paint.setColor(outer);
canvas.scale(w, w);
canvas.drawOval(mRect, paint);
canvas.restore();
canvas.scale(w-5, w-5);
paint.setColor(inner);
canvas.rotate(-values[i]);
canvas.drawPath(path, paint);
canvas.restore();
x += w0;
}
} else {
float h0 = mHeight * 0.333333f;
float h = h0 - 32;
float y = h0*0.5f;
for (int i=0 ; i<3 ; i++) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(mWidth - (h*0.5f + 4.0f), y);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
paint.setColor(outer);
canvas.scale(h, h);
canvas.drawOval(mRect, paint);
canvas.restore();
canvas.scale(h-5, h-5);
paint.setColor(inner);
canvas.rotate(-values[i]);
canvas.drawPath(path, paint);
canvas.restore();
y += h0;
}
}
}
}
}
public void onSensorChanged(SensorEvent event) {
//Log.d(TAG, "sensor: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]);
synchronized (this) {
if (mBitmap != null) {
final Canvas canvas = mCanvas;
final Paint paint = mPaint;
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
for (int i=0 ; i<3 ; i++) {
mOrientationValues[i] = event.values[i];
}
} else {
float deltaX = mSpeed;
float newX = mLastX + deltaX;
int j = (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) ? 1 : 0;
for (int i=0 ; i<3 ; i++) {
int k = i+j*3;
final float v = mYOffset + event.values[i] * mScale[j];
paint.setColor(mColors[k]);
canvas.drawLine(mLastX, mLastValues[k], newX, v, paint);
mLastValues[k] = v;
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mLastX += mSpeed;
}
invalidate();
}
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
I have an image which is of rectangular dimension, eg 30 x 60 pixels
I want to rotate this image around the bottom center of the image, i.e
i want to set the pivot in the above example as (15, 60 )pixel.
I am using a drawble and matrix to get this done,
whatever i try i always end up rotating around center of the image.
Code is :
Bitmap bitmapOrg = BitmapFactory.decodeFile("/sdcard/DCIM/2010-06-01_15-32-42_821.jpg");
// float angle = (angle + 10.0f)%360.0f;
if(null !=bitmapOrg)
{
int width = bitmapOrg.getWidth();
int height = bitmapOrg.getHeight();
int newWidth = 15;
int newHeight = 15;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
/* Canvas c = new Canvas(bitmapOrg);
float px = ;
float py;
c.rotate(angle, px, py)*/
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// 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);
ImageView imageView = new ImageView(this);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
// center the Image
imageView.setScaleType(ScaleType.CENTER);
// imageView.layout(100, 300, 0, 0);
// linLayout.addView(imageView);
// add ImageView to the Layout
linLayout.addView(imageView,
new AbsoluteLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 10, 30
)
);
can anyone let me know how to get this rectified?
Are you translating to the point you want to rotate around before doing the rotation?
Check out this resource:
http://blogs.sonyericsson.com/developerworld/2010/05/31/android-tutorial-making-your-own-3d-list-part-2/
yes with the help of matrix you can rotate the images. After calling RotateBitmap() you can get the bitmap at any time using getBitmap().
public class RotateBitmap {
public static final String TAG = "RotateBitmap";
private Bitmap mBitmap;
private int mRotation;
private int mWidth;
private int mHeight;
private int mBitmapWidth;
private int mBitmapHeight;
public RotateBitmap( Bitmap bitmap, int rotation )
{
mRotation = rotation % 360;
setBitmap( bitmap );
}
public void setRotation( int rotation )
{
mRotation = rotation;
invalidate();
}
public int getRotation()
{
return mRotation % 360;
}
public Bitmap getBitmap()
{
return mBitmap;
}
public void setBitmap( Bitmap bitmap )
{
mBitmap = bitmap;
if ( mBitmap != null ) {
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
invalidate();
}
}
private void invalidate()
{
Matrix matrix = new Matrix();
int cx = mBitmapWidth / 2;
int cy = mBitmapHeight / 2;
matrix.preTranslate( -cx, -cy );
matrix.postRotate( mRotation );
matrix.postTranslate( cx, cx );
RectF rect = new RectF( 0, 0, mBitmapWidth, mBitmapHeight );
matrix.mapRect( rect );
mWidth = (int)rect.width();
mHeight = (int)rect.height();
}
public Matrix getRotateMatrix()
{
Matrix matrix = new Matrix();
if ( mRotation != 0 ) {
int cx = mBitmapWidth / 2;
int cy = mBitmapHeight / 2;
matrix.preTranslate( -cx, -cy );
matrix.postRotate( mRotation );
matrix.postTranslate( mWidth / 2, mHeight / 2 );
}
return matrix;
}
public int getHeight()
{
return mHeight;
}
public int getWidth()
{
return mWidth;
}
public void recycle()
{
if ( mBitmap != null ) {
mBitmap.recycle();
mBitmap = null;
}
}
}