I have to implement functionality to rotate image through onTouchListener(). Please provide me sample code to rotate image. Please help me.
Thanks in Advance.
Here is sample code to rotate an image.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
baseView = (View) findViewById(R.id.baseView);
turntable = (ImageView) findViewById(R.id.turntable);
turntable.setOnTouchListener(onTableTouched);
baseView.setOnTouchListener(onTableTouched);
}
public android.view.View.OnTouchListener onTableTouched = new android.view.View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent evt) {
double r = Math.atan2(evt.getX() - turntable.getWidth() / 2,
(turntable.getHeight() / 2) - evt.getY());
int rotation = (int) Math.toDegrees(r);
Log.i("R is ", ""+r);
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
}
if (evt.getAction() == MotionEvent.ACTION_MOVE) {
x= evt.getX();
y= evt.getY();
updateRotation(rotation);
}
if (evt.getAction() == MotionEvent.ACTION_UP) {
//
}
return true;
}
};
private void updateRotation(double rot) {
float newRot = new Float(rot);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.orsl_circle_transparent);
Matrix matrix = new Matrix();
// matrix.setTranslate(getWindowManager().getDefaultDisplay().getWidth()/2, getWindowManager().getDefaultDisplay().getHeight());
matrix.postRotate(newRot,bitmap.getWidth()/2,bitmap.getHeight()/2);
// matrix.setSinCos(newRot, newRot/2, 100, 100);
// matrix.postRotate(newRot);
Log.i("THE ROATTION ", " "+ newRot);
if(y>250)
{
Bitmap redrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap
.getWidth(), bitmap.getHeight(), matrix, true);
turntable.setImageBitmap(redrawnBitmap);
}else
{
Bitmap redrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap
.getWidth(), bitmap.getHeight(), matrix, true);
turntable.setImageBitmap(redrawnBitmap);
Log.i("GUITAR _IMAGE", "");
}
}
you need to use an xml in type of "tween animation".
than, from the java code you can make a view act acording to this xml.
here is a link that help:
http://www.edumobile.org/android/android-beginner-tutorials/tween-animation/
Related
I want to create application like this.
Flood fill algorithm
I applied that code and it is working fine with JPG or PNG file.
But I want to use that algorithm with Vector drawable imageview
Vector drawable imageview before flood fill
After flood fill of vector imageview
Expected result should be like this (Flood fill work perfectly when I set JPG or PNG file)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flood_fill);
iv_FloodFillActivity_image = findViewById(R.id.iv_FloodFillActivity_image);
iv_FloodFillActivity_image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
floodColor(event.getX(), event.getY());
}
return true;
}
});
}
private void floodColor(float x, float y) {
final Point p1 = new Point();
p1.x = (int) x;// X and y are co - ordinates when user clicks on the screen
p1.y = (int) y;
Bitmap bitmap = getBitmapFromVectorDrawable(iv_FloodFillActivity_image.getDrawable());
//bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
int pixel = bitmap.getPixel((int) x, (int) y);
int[] sourceColorRGB = new int[]{
Color.red(pixel),
Color.green(pixel),
Color.blue(pixel)
};
final int targetColor = Color.parseColor("#FF2200");
QueueLinearFloodFiller queueLinearFloodFiller = new QueueLinearFloodFiller(bitmap, sourceColor, targetColor);
int toleranceHex = Color.parseColor("#545454");
int[] toleranceRGB = new int[]{
Color.red(toleranceHex),
Color.green(toleranceHex),
Color.blue(toleranceHex)
};
queueLinearFloodFiller.setTolerance(toleranceRGB);
queueLinearFloodFiller.setFillColor(targetColor);
queueLinearFloodFiller.setTargetColor(sourceColorRGB);
queueLinearFloodFiller.floodFill(p1.x, p1.y);
bitmap = queueLinearFloodFiller.getImage();
iv_FloodFillActivity_image.setImageBitmap(bitmap);
}
private Bitmap getBitmapFromVectorDrawable(Drawable drawable) {
try {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
return null;
}
}
Check Class : QueueLinearFloodFiller
How can I use vector drawable?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am making photo editing application, in my activity I have bitmap that is going to erase on touch when it's not zoomed or rotated its drawing perfectly but after I zoom or rotate bitmap, eraser is not erased at touched points.its erased on some other position according bitmap scaled.
how can I resolve this, please help me.
Drawingview.java
public class DrawingView extends ImageView implements View.OnTouchListener,MatrixGestureDetector.OnMatrixChangeListener {
private int ERASE = 1;
private int ZOOMTOUCH = 5;
private Matrix matrix = new Matrix();
Matrix inverse = new Matrix();
MatrixGestureDetector mgd = new MatrixGestureDetector(matrix, this);
#Override
public void onChange(Matrix matrix) {
invalidate();
}
public interface ActionListener {
void onActionCompleted(int i);
}
public void setImageBitmap(Bitmap bm) {
if (bm != null) {
bmp = bm;
orgBit = bm.copy(Bitmap.Config.ARGB_8888, true);
Bitmap2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
c2 = new Canvas();
c2.setBitmap(Bitmap2);
c2.drawBitmap(bmp, 0, 0, null);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.concat(matrix);
canvas.drawBitmap(Bitmap2,0,0, null);
if (c2 != null) {
Paint p;
if (!updateOnly) {
if (isTouched) {
paint = getPaintByMode(MODE, brushSize);
c2.drawPath(tPath, paint);
isTouched = false;
} else if (curIndx >= 0 && drawOnLasso) {
redrawCanvas();
}
}
if (MODE == ERASE) {
p = new Paint();
p.setColor(SupportMenu.CATEGORY_MASK);
erPaint.setStrokeWidth(updatebrushsize(erps, scale));
canvas.drawCircle(f887X, f888Y, (float) (brushSize / 2), erPaint);
canvas.drawCircle(f887X, f888Y + ((float) offset), updatebrushsize(ImageUtils.dpToPx(getContext(), 7), scale), p);
}
if (MODE == ZOOMTOUCH) {
}
updateOnly = false;
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MODE == ERASE) {
f887X = event.getX();
f888Y = event.getY() - ((float) offset);
isTouched = true;
switch (event.getAction()) {
case 0:
paint.setStrokeWidth((float) brushSize);
tPath = new Path();
tPath.moveTo(f887X, f888Y);
drawPath.moveTo(f887X, f888Y);
invalidate();
break;
case 1:
drawPath.lineTo(f887X, f888Y);
tPath.lineTo(f887X, f888Y);
invalidate();
changesIndx.add(curIndx + 1, new Path(tPath));
brushIndx.add(curIndx + 1, Integer.valueOf(brushSize));
modeIndx.add(curIndx + 1, Integer.valueOf(MODE));
vectorPoints.add(curIndx + 1, null);
lassoIndx.add(curIndx + 1, Boolean.valueOf(insidCutEnable));
tPath.reset();
curIndx++;
clearNextChanges();
break;
case 2:
drawPath.lineTo(f887X, f888Y);
tPath.lineTo(f887X, f888Y);
invalidate();
break;
default:
return false;
}
}
if (MODE == ZOOMTOUCH) {
matrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
mgd.onTouchEvent(event);
}
return true;
}
}
class MatrixGestureDetector {
private static final String TAG = "MatrixGestureDetector";
private int ptpIdx = 0;
private Matrix mTempMatrix = new Matrix();
private Matrix mMatrix;
private OnMatrixChangeListener mListener;
private float[] mSrc = new float[4];
private float[] mDst = new float[4];
private int mCount;
interface OnMatrixChangeListener {
void onChange(Matrix matrix);
}
public MatrixGestureDetector(Matrix matrix, MatrixGestureDetector.OnMatrixChangeListener listener) {
this.mMatrix = matrix;
this.mListener = listener;
}
public void onTouchEvent(MotionEvent event) {
if (event.getPointerCount() > 2) {
return;
}
int action = event.getActionMasked();
int index = event.getActionIndex();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
int idx = index * 2;
mSrc[idx] = event.getX(index);
mSrc[idx + 1] = event.getY(index);
mCount++;
ptpIdx = 0;
break;
case MotionEvent.ACTION_MOVE:
for (int i = 0; i < mCount; i++) {
idx = ptpIdx + i * 2;
mDst[idx] = event.getX(i);
mDst[idx + 1] = event.getY(i);
}
mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount);
mMatrix.postConcat(mTempMatrix);
if (mListener != null) {
mListener.onChange(mMatrix);
}
System.arraycopy(mDst, 0, mSrc, 0, mDst.length);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerId(index) == 0) ptpIdx = 2;
mCount--;
break;
}
}
}
found the solution thanx to pskink, on this link Android ImageView Scaling and translating issue
by using invert matrix in layer#contain method.
I am just creating an application in which I need to drill into the bitmap, I succeed for that also but bitmap drill is lagging as I touch image view. Any help on this is really appreciated...Thanks..
Here is Main File
public class MainActivity extends Activity{
int x, y;
Bitmap background,foreground;
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.img);
background = BitmapFactory.decodeResource(getResources(), R.mipmap.mug_shot);
foreground = BitmapFactory.decodeResource(getResources(), R.mipmap.poster);
iv.setImageBitmap(combineTwoBitmaps(background, foreground));
iv.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View view, MotionEvent event)
{
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = (int) (event.getRawX()+100);
y = (int) (event.getY()+100);
System.out.println("X : "+ x +" Y : "+ y);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(combineTwoBitmaps(background,foreground));
System.out.println("Hello this is Test2");
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
});
}
private Bitmap punchAHoleInABitmap(Bitmap foreground)
{
System.out.println("Hello this is Tesyt");
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x1 = (float) ((x*.5) + (radius * .5));
float y1 = (float) ((y*.5) + (radius * .5));
System.out.println("X1 : "+ x1 +" Y1 : "+ y1);
canvas.drawCircle(x1, y1, 50, paint);
return bitmap;
}
private Bitmap combineTwoBitmaps(Bitmap background, Bitmap foreground) {
Bitmap combinedBitmap = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());
Canvas canvas = new Canvas(combinedBitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(background, 0, 0, paint);
canvas.drawBitmap(foreground, 0, 0, paint);
return combinedBitmap;
}
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
ACTION_MOVE is called many times when users slide the screen. This means you will create quite amount of bitmaps in short time.
With GestureDetector you can detect exact one slide/swipe/fling.
I have a GridView of images, which are all in the /res directory (come with the app). When I open one of them, there is no problem. But, I want to be able to scroll between them also in the same way that's done in the gallery, i.e. sliding the finger on the image will cause the next image to appear. Is there any way to do that?
Thanks!
You can use ViewPager
See android viewPager implementation for some good links to learn how to implement it.
I ended up creating a simple implementation of my own:
public class PicView extends View{
private int mBackgroundPicPosition;
private Bitmap mBackgroundPic;
private int m_touchStartPosX;
private EventsActivity m_mainActivity;
private int m_viewWidth;
private int m_viewHeight;
private int m_backgroundX;
private Integer[] m_picIDs;
public PicView(Context context, Integer[] picIDs) {
super(context);
m_mainActivity = (EventsActivity)context;
m_viewWidth = m_mainActivity.mMetrics.widthPixels;
m_viewHeight = m_mainActivity.mMetrics.heightPixels;
m_picIDs = picIDs;
}
public void setBackground(int position) {
Options opts = new Options();
mBackgroundPicPosition = position;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), m_picIDs[position], opts);
mBackgroundPic = BitmapFactory.decodeResource(getResources(), m_picIDs[position], opts);
int picHeight = bitmap.getHeight();
int picWidth = bitmap.getWidth();
mBackgroundPic.recycle();
float xScale, yScale, scale;
if (picWidth > picHeight) {
// rotate the picture
Matrix matrix = new Matrix();
matrix.postRotate(-90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
picHeight = bitmap.getHeight();
picWidth = bitmap.getWidth();
matrix = null;
}
xScale = ((float)m_viewWidth)/ picWidth;
yScale = ((float)m_viewHeight) / picHeight;
scale = (xScale <= yScale) ? xScale : yScale;
m_backgroundX = (xScale >= yScale) ? (m_viewWidth - (int)(picWidth * scale)) / 2 : 0;
mBackgroundPic = Bitmap.createScaledBitmap(bitmap, (int)(picWidth * scale), (int)(picHeight * scale), true);
bitmap = null;
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
// draw the background
canvas.drawBitmap(mBackgroundPic, m_backgroundX, 0, null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
m_touchStartPosX = X;
break;
case MotionEvent.ACTION_UP:
//check to see if sliding picture
if (X <= m_touchStartPosX) {
// slide to the left
setBackground(getNextPosition());
} else {
// slide to the right
setBackground(getPrevPosition());
}
m_touchStartPosX = -1;
break;
}
invalidate();
return true;
}
private int getPrevPosition() {
if (mBackgroundPicPosition == 0) {
return m_picIDs.length - 1;
} else {
return mBackgroundPicPosition - 1;
}
}
private int getNextPosition() {
if (mBackgroundPicPosition == m_picIDs.length - 1) {
return 0;
} else {
return mBackgroundPicPosition + 1;
}
}
I want rotate image in both the ways Clockwise as well as Anti clock wise.
I had try but not rotate image both the way,
so plz give me solution for my problem if you know..
Thanks in Advance.................///
Use the code below
public class Rotateimage extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
// or just load a resource from the res/drawable directory:
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flo);
// find the width and height of the screen:
Display d = getWindowManager().getDefaultDisplay();
int x = d.getWidth();
int y = d.getHeight();
// get a reference to the ImageView component that will display the image:
ImageView img1 = (ImageView)findViewById(R.id.imageView1);
// scale it to fit the screen, x and y swapped because my image is wider than it is tall
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, y, x, true);
// create a matrix object
Matrix matrix = new Matrix();
matrix.postRotate(45, 90, 180);
// create a new bitmap from the original using the matrix to transform the result
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
// display the rotated bitmap
img1.setImageBitmap(rotatedBitmap);
}}
Here is the base code to load a bitmap and rotate it left or right:
// Load a bitmap from a drawable, make sure this drawable exists in your project
Bitmap sprite = BitmapFactory.decodeResource(this.getResources(),
R.drawable.ic_launcher);
// Create two matrices that will be used to rotate the bitmap
Matrix rotateRight = new Matrix();
Matrix rotateLeft = new Matrix();
// Set the matrices with the desired rotation 90 or -90 degrees
rotateRight.preRotate(90);
rotateLeft.preRotate(-90);
// Create bitmaps based on the loaded bitmap 'sprite' and apply one of
// the rotation matrices
Bitmap rSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateRight, true);
Bitmap lSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateLeft, true);
Now go and use rSprite and lSprite.
Here is a full sample that actually draws the bitmaps to screen:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new drawView(this));
}
private class drawView extends View{
public drawView(Context context){
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Load a bitmap from a drawable, make sure this drawable exists in your project
Bitmap sprite = BitmapFactory.decodeResource(this.getResources(),
R.drawable.ic_launcher);
// Create two matrices that will be used to rotate the bitmap
Matrix rotateRight = new Matrix();
Matrix rotateLeft = new Matrix();
// Set the matrices with the desired rotation 90 or -90 degrees
rotateRight.preRotate(90);
rotateLeft.preRotate(-90);
// Create bitmaps based on the loaded bitmap 'sprite' and apply one of
// the rotation matrices
Bitmap rSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateRight, true);
Bitmap lSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateLeft, true);
//Draw the first unrotated sprite at the top left of the screen
canvas.drawBitmap(sprite, 0, 0, null);
//Draw the rotated right sprite on the 2nd row
canvas.drawBitmap(rSprite, 0, sprite.getHeight() + 5, null);
//Draw the rotated left sprite on the 3rd row
canvas.drawBitmap(lSprite, 0, sprite.getHeight() * 2 + 5, null);
}
}
}
use this code hope it will be helpful...
you must have to write this method to do rotate operation
public void paintFromCenter(float angle, Canvas c) {
Bitmap b = sprite;
Bitmap h = b;
Matrix matrix = new Matrix();
matrix.postRotate(angle, h.getWidth() / 2, h.getHeight());
matrix.postTranslate(getX(), getY());
// canvas.drawBitmap(bitmap, matrix, new Paint());
Bitmap bmp2 = Bitmap.createBitmap(h, 0, 0, frameWidth, frameHeight,
matrix, true);
c.drawBitmap(h, matrix, null);
}
in your program you have to write onTouchEvent() method
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
edX = (int) event.getX();
edY = (int) event.getY();
if ((edX > objectSprite.getX()
&& edX < objectSprite.getX() + objectSprite.getWidth()
&& edY > objectSprite.getY() && edY < objectSprite.getY()
+ objectSprite.getHeight())) {
}
}
if (action == MotionEvent.ACTION_MOVE) {
emX = (int) event.getX();
emY = (int) event.getY();
if (edX < emX && angle <= 90) {
update(canvas);
CHAR = 'D';
} else if (edX > emX && angle > 0) {
update(canvas);
CHAR = 'U';
}
if (edY < emY && angle <= 90) {
update(canvas);
CHAR = 'L';
} else if (edY > emY && angle >= 0) {
update(canvas);
CHAR = 'R';
}
}
return true;
}
and you have to create update() method to rotate your angle on touch event angle can be define as your choice. Initially i have declare
int angle=1;
public void update(Canvas canvas) {
switch (CHAR) {
case 'D':
angle += 1;
break;
case 'U':
angle -= 1;
break;
case 'R':
angle -= 1;
break;
case 'L':
angle += 1;
break;
}
}
Now you have to draw your object in draw() method like this
public void draw() {
objectSprite.paintFromCenter(angle, canvas);
}
You just add this simple code to your button
imVCature_pic.setRotation(imVCature_pic.getRotation() + 90);
Matrix mat = new Matrix();
mat.preRotate(angle);///in degree
Bitmap mBitmap = Bitmap.createBitmap(originalBmp, 0, 0, modWidth, modHeight, mat, true);
//originalBmp -> original img as bitmap
//modHeight -> new height
//modWidth -> new width
use the above code.