How to Crop Bitmap inside Fragment? - android

Please Help to solve this problem...
First Fragment
Here this is a 1stFragment file sends the string of encoded bitmap
tmp = getArguments().getString("PHOTO");
byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
ByteArrayOutputStream b=new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG,100, b);
bm =b.toByteArray();
temp=Base64.encodeToString(bm, Base64.DEFAULT);Fragment fr = new CropToolActivity();
fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
args = new Bundle();
args.putString("PHOTO", temp);
fr.setArguments(args);
ft.replace(R.id.frame,fr);
ft.commit();
CropToolActivity
Here this is a 2ndFragment file receives the string of encoded bitmap
also set the CropView ti the layout
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.croptool, container, false);
myCropView = (CropView)view.findViewById(R.id.crop_tool);
myCropView = new CropView(getActivity().getApplicationContext());
tmp = getArguments().getString("PHOTO");
byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
myCropView.setImageBitmap(bmp);
croptool.xml
This is a XML file for 2nd Fragment layout
<com.tcss.photostyle.CropView
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:id="#+id/crop_tool" />
</LinearLayout>
CropView.Java
Here this is a croptool java file to demonstrate the Croptool on bitmap
public class CropView extends ImageView {
Paint paint = new Paint();
private int initial_size = 300;
private static Point leftTop, rightBottom, center, previous;
private static final int DRAG= 0;
private static final int LEFT= 1;
private static final int TOP= 2;
private static final int RIGHT= 3;
private static final int BOTTOM= 4;
private int imageScaledWidth,imageScaledHeight;
// Adding parent class constructors
public CropView(Context context) {
super(context);
initCropView();
}
public CropView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initCropView();
}
public CropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initCropView();
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(leftTop.equals(0, 0))
resetPoints();
canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
previous.set((int)event.getX(), (int)event.getY());
break;
case MotionEvent.ACTION_MOVE:
if(isActionInsideRectangle(event.getX(), event.getY())) {
adjustRectangle((int)event.getX(), (int)event.getY());
invalidate(); // redraw rectangle
previous.set((int)event.getX(), (int)event.getY());
}
break;
case MotionEvent.ACTION_UP:
previous = new Point();
break;
}
return true;
}
private void initCropView() {
paint.setColor(Color.YELLOW);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(5);
leftTop = new Point();
rightBottom = new Point();
center = new Point();
previous = new Point();
}
public void resetPoints() {
center.set(getWidth()/2, getHeight()/2);
leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2);
rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size);
}
private static boolean isActionInsideRectangle(float x, float y) {
int buffer = 10;
return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false;
}
private boolean isInImageRange(PointF point) {
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Calculate the scaled dimensions
imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]);
imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]);
return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false;
}
private void adjustRectangle(int x, int y) {
int movement;
switch(getAffectedSide(x,y)) {
case LEFT:
movement = x-leftTop.x;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
leftTop.set(leftTop.x+movement,leftTop.y+movement);
break;
case TOP:
movement = y-leftTop.y;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
leftTop.set(leftTop.x+movement,leftTop.y+movement);
break;
case RIGHT:
movement = x-rightBottom.x;
if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
break;
case BOTTOM:
movement = y-rightBottom.y;
if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
break;
case DRAG:
movement = x-previous.x;
int movementY = y-previous.y;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) {
leftTop.set(leftTop.x+movement,leftTop.y+movementY);
rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY);
}
break;
}
}
private static int getAffectedSide(float x, float y) {
int buffer = 10;
if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer))
return LEFT;
else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer))
return TOP;
else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer))
return RIGHT;
else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer))
return BOTTOM;
else
return DRAG;
}
public byte[] getCroppedImage() {
BitmapDrawable drawable = (BitmapDrawable)getDrawable();
float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2);
float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2);
Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
cropped.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
}

Here is a method for cropping bitmap from center, assume that newWidth < bitmap.getWidth() and newHeight < bitmap.getHeight()
public Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) {
double x = (bitmap.getWidth() - newWidth) / 2;
double y = (bitmap.getHeight() - newHeight) / 2;
Bitmap b = Bitmap.createBitmap((int)newWidth, (int)newHeight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawBitmap(bitmap, new Rect((int)x , (int)y, (int)(x + newWidth), (int)(y + newHeight)), new Rect(0, 0, (int)newWidth, (int)newHeight), null);
return b;
}

Related

Get Touch Coordinates Relative To A Custom ImageView

I implemented custom ImageView. Because my image is large I'm using ScrollView and HorizontalScrollView to scrolling image. I want to draw circle in onTouch event, but its not work in all cases. When I scroll image and fire touch event the x,y coordinates apply to current visible sector of image ( in top right corner its e.g. 0x0, but when I scroll somwhere and in visible top corner it will be 0x0 too), but circle is drawing according to image size.
Another problem is that app could be used on various screen size.
I know that it xamarin c# but in native Android it should be the same. Anyone knows how to draw/get coordinates properly?
public class DrawViewInside : ImageView
{
public static Bitmap bitmapInside;
private Paint paint = new Paint();
private Point point = new Point();
private Canvas mCanvas;
private static Bitmap mutableBitmap;
private Context mContext;
public static Bitmap b;
public void SetCarId(int id)
{
carId = id;
}
public DrawViewInside(Context context, IAttributeSet attrs) : base(context, attrs)
{
mContext = context;
setDefault(drawable);
}
public void SetBitmap(int drawableId)
{
setDefault(drawableId);
Invalidate();
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.GetSize(widthMeasureSpec);
int height = width;
var metrics = Resources.DisplayMetrics;
if (b != null)
{
SetMeasuredDimension(b.Width, b.Height);
}
}
public async void setDefault(int drawableId)
{
BitmapFactory.Options options = await GetBitmapOptionsOfImage(drawableId);
paint.Color = Color.Red;
paint.StrokeWidth = 15;
paint.SetStyle(Paint.Style.Stroke);
var metrics = Resources.DisplayMetrics;
var widthInDp = ConvertPixelsToDp(metrics.WidthPixels);
var heightInDp = ConvertPixelsToDp(metrics.HeightPixels);
b = BitmapFactory.DecodeResource(Resources, drawableId);esources, drawableId);
mutableBitmap = b.Copy(Bitmap.Config.Argb8888, true);
mCanvas = new Canvas(mutableBitmap);
mCanvas.Save();
}
protected override void OnDraw(Canvas canvas)
{
DrawCircle(canvas);
}
private void DrawCircle(Canvas canvas)
{
if (mCanvas == null)
{
setDefault(drawable);
}
else
{
mCanvas.Restore();
mCanvas.DrawCircle(point.x, point.y, 10, paint);
mCanvas.Save();
canvas.DrawBitmap(mutableBitmap, 0, 0, paint);
bitmapInside = mutableBitmap;
}
}
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
break;
case MotionEventActions.Up:
Activity act = (Activity)mContext;
float viewX = e.RawX - this.Left;
float viewY = e.RawY - this.Top;
point.x = viewX;// e.RawX;
point.y = viewY;// e.RawY;
break;
}
Invalidate();
return true;
}
}
public class Point
{
public float x, y;
}
I found solution. Just replace
float viewX = e.RawX - this.Left;
float viewY = e.RawY - this.Top;
point.x = viewX;// e.RawX;
point.y = viewY;// e.RawY;
with
float viewX = e.RawX;// - this.Left;
float viewY = e.RawY;// - this.Top;
int[] viewCoords = new int[2];
this.GetLocationOnScreen(viewCoords);
point.x = viewX - viewCoords[0];// e.RawX;
point.y = viewY - viewCoords[1];// e.RawY;

How to set ontouch listener for something drawn using canvas: Android

I have a custom view in which i am drawing one big circle and a small circle on the edge of this big circle.
I would like to move the small circle and so would like to have a ontouch listener only for the small circle.
Could some please tell me how to set the ontouch listener for only the small circle.
public class ThermoView extends View{
private ImageView mThermostatBgrd;
private ImageView mCurTempArrow;
private ImageView mSetPointIndicator;
public static final int THEMROSTAT_BACKGROUND = 0;
public static final int THEMROSTAT_CURR_TEMP = 1;
public static final int THEMROSTAT_SET_POINT = 2;
private float mViewCentreX;
private float mViewCentreY;
private float mThermostatRadius;
private Canvas mCanvas;
private Paint mPaint;
private Paint mPaintCurTemp;
private Paint mPaintSetTemp;
private Paint mPaintOverrideTemp;
private Paint mPaintCurTempIndicator;
private Boolean mManualOverride = false;
private double mManualOverrideAngle;
private int mMaxTemp = 420;
private int mMinTemp = 120;
private RectF mCurrTempBox;
private float mCurTempCircleX;
private float mCurTempCircleY;
private Matrix mMatrix;
public double getManualOverrideAngle() {
return mManualOverrideAngle;
}
public void setManualOverrideAngle(double mManualOverrideAngle) {
this.mManualOverrideAngle = mManualOverrideAngle;
}
public RectF getCurrTempBox() {
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
return mCurrTempBox;
}
public void setCurrTempBox(RectF mCurrTempBox) {
this.mCurrTempBox = mCurrTempBox;
}
public Boolean getManualOverride() {
return mManualOverride;
}
public void setManualOverride(Boolean mManualOverride) {
this.mManualOverride = mManualOverride;
}
public ThermoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path smallCirle = new Path();
int viewWidth = getMeasuredWidth();
int viewHeight = getMeasuredHeight();
mViewCentreX = viewWidth/2;
mViewCentreY = viewHeight/2;
float paddingPercent = 0.2f;
int thermostatThickness = 20;
mThermostatRadius = (int) ((Math.min(mViewCentreX, mViewCentreY)*(1- paddingPercent)));
if (mPaint == null){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(thermostatThickness);
mPaint.setColor(0xffff0000);
Path arcPath = new Path();
RectF container = new RectF();
container.set(mViewCentreX - mThermostatRadius, mViewCentreY - mThermostatRadius,
mViewCentreX + mThermostatRadius, mViewCentreY + mThermostatRadius);
arcPath.addArc(container, 120, 300);
canvas.drawPath(arcPath, mPaint);
int dummyCurTemp = 200;
if (mPaintCurTemp == null){
mPaintCurTemp = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaintCurTemp.setTextAlign(Align.CENTER);
mPaintCurTemp.setTextSize(100);
canvas.drawText(String.valueOf(dummyCurTemp), mViewCentreX, mViewCentreY, mPaintCurTemp);
if (this.mManualOverride == false){
double angle = (360-120-(300/(mMaxTemp - mMinTemp))*(dummyCurTemp-mMinTemp))*(Math.PI/180);
this.mCurTempCircleX = (float) (mViewCentreX + mThermostatRadius*(Math.cos(angle)));
this.mCurTempCircleY = (float) (mViewCentreY - mThermostatRadius*(Math.sin(angle)));
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
if (mPaintCurTempIndicator == null){
mPaintCurTempIndicator = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaintCurTempIndicator.setStyle(Paint.Style.STROKE);
mPaintCurTempIndicator.setStrokeWidth(thermostatThickness/2);
mPaintCurTempIndicator.setColor(Color.GREEN);
mCurrTempBox.set(mCurTempCircleX-50, mCurTempCircleY-50, mCurTempCircleX+50, mCurTempCircleY+50);
smallCirle.addCircle(mCurTempCircleX, mCurTempCircleY, 50, Direction.CW);
canvas.drawPath(smallCirle, mPaintCurTempIndicator);
}else{
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
if (mPaintCurTempIndicator == null){
mPaintCurTempIndicator = new Paint(Paint.ANTI_ALIAS_FLAG);
}
if (mMatrix == null){
mMatrix = new Matrix();
}
//mMatrix.reset();
mMatrix.postRotate((float) (mManualOverrideAngle), mViewCentreX,mViewCentreY);
//mMatrix.postTranslate(mViewCentreX, mViewCentreY);
mPaintCurTempIndicator.setStyle(Paint.Style.STROKE);
mPaintCurTempIndicator.setStrokeWidth(thermostatThickness/2);
mPaintCurTempIndicator.setColor(Color.GREEN);
canvas.concat(mMatrix);
smallCirle.addCircle(mCurTempCircleX, mCurTempCircleY, 50, Direction.CW);
canvas.drawPath(smallCirle, mPaintCurTempIndicator);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialX = event.getX();
mInitialY = event.getY();
RectF touchedAt = new RectF(mInitialX-10, mInitialY-10, mInitialX+10, mInitialY+10);
RectF indicatorAt = mThermoStatView.getCurrTempBox();
if (RectF.intersects(indicatorAt, touchedAt)){
this.isIndicatorSelected = true;
mThermoStatView.setManualOverride(true);
}
break;
case MotionEvent.ACTION_MOVE:
if (this.isIndicatorSelected == true){
float angle = (float) (180*Math.atan2(event.getY() - mThermostatHeight/2, event.getX() - mThermostatWidth/2) / Math.PI);
mThermoStatView.setManualOverrideAngle(angle);
mThermoStatView.invalidate();
//mThermoStatView.requestLayout();
}
break;
case MotionEvent.ACTION_UP:
if (this.isIndicatorSelected == true){
this.isIndicatorSelected = false;
}
break;
}
return true;
}
}
try this (this is a little modified version of MyView i already posted as an answer for your previous question):
public class MyView extends View {
private final static String TAG = "Main.MyView";
private static final float CX = 0;
private static final float CY = 0;
private static final float RADIUS = 20;
private static final float BIGRADIUS = 50;
private static final int NORMAL_COLOR = 0xffffffff;
private static final int PRESSED_COLOR = 0xffff0000;
private Paint mPaint;
private Path mSmallCircle;
private Path mCircle;
private Matrix mMatrix;
private float mAngle;
private int mSmallCircleColor;
public MyView(Context context) {
super(context);
mPaint = new Paint();
mSmallCircle = new Path();
mSmallCircle.addCircle(BIGRADIUS + RADIUS + CX, CY, RADIUS, Direction.CW);
mSmallCircleColor = NORMAL_COLOR;
mCircle = new Path();
mCircle.addCircle(0, 0, BIGRADIUS, Direction.CW);
mMatrix = new Matrix();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
mSmallCircleColor = NORMAL_COLOR;
invalidate();
return false;
}
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
float r = 0;
if (action == MotionEvent.ACTION_DOWN) {
float[] pts = {
BIGRADIUS + RADIUS + CX, CY
};
mMatrix.mapPoints(pts);
r = (float) Math.hypot(event.getX() - pts[0], event.getY() - pts[1]);
}
if (r < RADIUS) {
mSmallCircleColor = PRESSED_COLOR;
mAngle = (float) (180 * Math.atan2(event.getY() - h2, event.getX() - w2) / Math.PI);
invalidate();
return true;
}
return false;
}
#Override
protected void onDraw(Canvas canvas) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mMatrix.reset();
mMatrix.postRotate(mAngle);
mMatrix.postTranslate(w2, h2);
canvas.concat(mMatrix);
mPaint.setColor(0x88ffffff);
canvas.drawPath(mCircle, mPaint);
mPaint.setColor(mSmallCircleColor);
canvas.drawPath(mSmallCircle, mPaint);
}
}
You can get the rectangle of your touch point and the rectangle(position) of your inner circle and check if they cross over with the Intersects method.
http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html#intersects(java.awt.Rectangle)
Your canvas onTouchListener can do whatever it needs to do if the touchpoint intersect your circle.
e.g:
// Create a rectangle from the point of touch
Rect touchpoint = new Rect(x,y,10,10);
// Create a rectangle from the postion of the circle.
Rect myCircle=new Rect(10,10,20,20);
if (Rect.intersects(myCircle,touchpoint)){
Log.d("The circle was touched");
}

How to draw a bitmap from sdcard to custom ondraw method

I have a image on sdcard can anyone tell me how to draw the image from sdcard onto the custom ondraw method
I got the answer actually to draw a image from sdcard we have to intialize the image again in the function below
public void surfaceCreated(SurfaceHolder holder)
{
ball=BitmapFactory.createScaledBitmap(src,width,height,true);
bgr=BitmapFactory.decodeFile("/sdcard/1364275090569.jpg");
}
Actually this is my code and in this i am able to draw and customly move the image over background through the images placed in the resource folder but when i load a image instead from the sdcard and then implement it the application gives error
public class Preview extends Activity{
BallBounces ball;
public static int wd;
public static int ht;
public static String txt;
public static String path;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Intent i=getIntent();
ball = new BallBounces(this);
setContentView(ball);
txt=i.getStringExtra("bpath");
path=i.getStringExtra("path");
wd= getWindowManager().getDefaultDisplay().getWidth();
ht=getWindowManager().getDefaultDisplay().getHeight();
}
}
class BallBounces extends SurfaceView implements SurfaceHolder.Callback {
private int mActivePointerId = INVALID_POINTER_ID;
private static final int INVALID_POINTER_ID = -1;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public float mPosX=0;
public float mPosY=0;
public float mLastTouchX;
public float mLastTouchY;
//For Fetching image
private Bitmap bmp;
private Drawable image;
private byte[] byteArray;
private ByteArrayBuffer baf = null;
int wid =Preview.wd, hght = Preview.ht;
//For Rotation
int direction = 0;
int degree = 0;
String twxt=Preview.txt;
String pth=Preview.path;
float wdth,hgt;
private float newX ;
public float newY ;
private float rotateX;
private float rotateY;
private float imgX;
private float imgY;
GameThread thread;
public int screenW; //Device's screen width.
public int screenH; //Devices's screen height.
public int ballX; //Ball x position.
public int ballY; //Ball y position.
int initialY ;
float dY; //Ball vertical speed.
int ballW;
int ballH;
int bgrW;
int bgrH;
int angle;
int bgrScroll;
int dBgrY; //Background scroll speed.
float acc;
Bitmap ball, bgr, bgrReverse;
boolean reverseBackroundFirst;
boolean ballFingerMove;
Bitmap d;
//Measure frames per second.
long now;
int framesCount=0;
int framesCountAvg=0;
long framesTimer=0;
Paint fpsPaint=new Paint();
//Frame speed
long timeNow;
long timePrev = 0;
long timePrevFrame = 0;
long timeDelta;
public BallBounces(Context context) {
super(context);
ball = BitmapFactory.decodeResource(getResources(), R.drawable.bubble);//load image
bgr = BitmapFactory.decodeResource(getResources(), R.drawable.grd); //Load a background.
bgrW = bgr.getWidth();
bgrH = bgr.getHeight();
ballW = ball.getWidth();
ballH = ball.getHeight();
image =new BitmapDrawable(context.getResources() , ball);
imgX=image.getIntrinsicWidth();
imgY=image.getIntrinsicHeight();
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
//Set thread
getHolder().addCallback(this);
setFocusable(true);
}
#Override
public void onSizeChanged (int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//This event-method provides the real dimensions of this custom view.
screenW = w;
screenH = h;
System.out.println(w+" X "+h);
bgr = Bitmap.createScaledBitmap(bgr, w, h, true); //Scale background to fit the screen.
bgrW = bgr.getWidth();
bgrH = bgr.getHeight();
}
//***************************************
//************* TOUCH *****************
//***************************************
#Override
public synchronized boolean onTouchEvent(MotionEvent ev) {
mScaleDetector.onTouchEvent(ev);
final int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
System.out.println("DOWN");
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
System.out.println("DOWN-POSITION--"+x+" X "+y);
mActivePointerId = ev.getPointerId(0);
}
if (action == MotionEvent.ACTION_MOVE) {
System.out.println("MOVE");
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
System.out.println("Moving points" +x+" X "+y);
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy=y-mLastTouchY;
mPosX += dx;
mPosY += dy;
newX=ev.getRawX();
newY=ev.getRawY();
System.out.println("Image Config" +newX+" X "+newY);
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
}
if (action == MotionEvent.ACTION_UP) {
System.out.println("UP");
mActivePointerId = INVALID_POINTER_ID;
}
if (action == MotionEvent.ACTION_CANCEL) {
System.out.println("CANCEL");
mActivePointerId = INVALID_POINTER_ID;
}
if (action == MotionEvent.ACTION_POINTER_UP) {
System.out.println("ACTN_POINTER_UP");
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
}
return true;
}
public BitmapDrawable writeOnDrawable(int drawableId, String text){
Rect bounds = new Rect();
Paint textPaint = new Paint();
textPaint.getTextBounds(twxt,0,twxt.length(),bounds);
float height = bounds.height();
float width = bounds.width();
wdth=width/2;
hgt=height/2;
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setStyle(Style.FILL_AND_STROKE);
paint.setColor(Color.WHITE);
paint.setTextSize(15);
Canvas canvas = new Canvas(bm);
int xPos =(int) ((bm.getWidth()/2)-wdth);
int yPos = (int) ((bm.getHeight()/2)-hgt) ;
canvas.drawText(text, xPos-(wdth/8),yPos+hgt, paint);
return new BitmapDrawable(bm);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect fromRect1 = new Rect(0, 0, bgrW - bgrScroll, bgrH);
Rect toRect1 = new Rect(bgrScroll, 0, bgrW, bgrH);
Rect fromRect2 = new Rect(bgrW - bgrScroll, 0, bgrW, bgrH);
Rect toRect2 = new Rect(0, 0, bgrScroll, bgrH);
if (!reverseBackroundFirst) {
canvas.drawBitmap(bgr, fromRect1, toRect1, null);
}
else{
canvas.drawBitmap(bgr, fromRect2, toRect2, null);
}
if(mPosX<0)
{
mPosX=0;
}
if(mPosX>screenW-ballW)
{
mPosX=screenW-ballW;
}
if(mPosY>screenH-ballH)
{
mPosY=screenH-ballH;
}
if(mPosY<0)
{
mPosY=0;
}
canvas.drawBitmap(ball, mPosX, mPosY, null);
canvas.drawText(mPosX+ " X "+mPosY, 40, 70, fpsPaint);
canvas.drawText(ballW+ " X "+ballH, 40, 100, fpsPaint);
canvas.drawText(screenW+ " X "+screenH, 40, 150, fpsPaint);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
thread = new GameThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class GameThread extends Thread {
private SurfaceHolder surfaceHolder;
private BallBounces gameView;
private boolean run = false;
public GameThread(SurfaceHolder surfaceHolder, BallBounces gameView) {
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
}
public void setRunning(boolean run) {
this.run = run;
}
public SurfaceHolder getSurfaceHolder() {
return surfaceHolder;
}
#Override
public void run() {
Canvas c;
while (run) {
c = null;
//limit frame rate to max 60fps
timeNow = System.currentTimeMillis();
timeDelta = timeNow - timePrevFrame;
if ( timeDelta < 16) {
try {
Thread.sleep(16 - timeDelta);
}
catch(InterruptedException e) {
}
}
timePrevFrame = System.currentTimeMillis();
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
//call methods to draw and process next fame
gameView.onDraw(c);
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}

Make new bitmap on the canvas from resource

I think that my problem is minor but I can't find solution. I am trying to make application which will help me to make WEB pages and I want to make application which will put graphic element on the screen.
I made drawable png images of rectangles and I can put them on the screen where I want, no problem, but I can not make new graphic/bitmap.
How I can put new graphics object on the screen when I press in meni DIV or iFrame?
public class Objects extends View {
private float X;
private float Y;
private Paint myPaint;
final String C_DIV = "DIV";
final String C_TABLE = "Table";
final String C_IFRAME = "iFrame";
final String C_LIST = "List";
Canvas canvas;
Bitmap divimg = BitmapFactory.decodeResource(getResources(), R.drawable.div);
Bitmap iframeimg = BitmapFactory.decodeResource(getResources(), R.drawable.iframe);
Bitmap img = null;
String objectname = " ";
public Objects(Context context) {
super(context);
myPaint = new Paint();
}
public void HTMLObjects(String object) {
Log.d(object, "see");
if (object.equals(C_DIV)) {
myPaint.setColor(Color.GREEN);
img = Bitmap.createBitmap(divimg);
objectname = "DIV";
}
if (object.equals(C_IFRAME)) {
myPaint.setColor(Color.BLUE);
img = Bitmap.createBitmap(iframeimg);
objectname = "iFrame";
}
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
X = (int) event.getX();
Y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
X = (int) event.getX();
Y = (int) event.getY();
break;
}
return true;
}
public void onDraw(Canvas canvas) {
if (img != null) {
canvas.drawBitmap(img, X - 50, Y - 50, myPaint);
canvas.drawText(objectname, X, Y - 50, myPaint);
}
invalidate();
}
}
This is a class which I am calling from the activity Workspace with
ob.HTMLObjects((String) item.getTitle());
and I am sending information which menu is pressed.
I do not know how to make new/different object/bitmap when I pressed DIV or iFrame.
Try these version. I replaces x,y,img,objectname with according lists:
public class Objects extends View {
private Paint myPaint;
public final String C_DIV="DIV";
public final String C_TABLE="Table";
public final String C_IFRAME="iFrame";
public final String C_LIST="List";
private Canvas canvas;
private Bitmap divimg= BitmapFactory.decodeResource(getResources(), R.drawable.div);
private Bitmap iframeimg=BitmapFactory.decodeResource(getResources(), R.drawable.iframe);
private List<Bitmap> images;
private List<Float> xs;
private List<Float> ys;
private List<String> objectNames;
public Objects(Context context) {
super(context);
myPaint = new Paint();
images = new ArrayList<Bitmap>();
xs = new ArrayList<Float>();
ys = new ArrayList<Float>();
objectNames = new ArrayList<String>();
}
public void HTMLObjects(String object){
Log.d(object, "see");
if (object.equals(C_DIV)) {
myPaint.setColor(Color.GREEN);
images.add(Bitmap.createBitmap(divimg));
objectNames.add("DIV");
xs.add(0F);
ys.add(0F);
}
if (object.equals(C_IFRAME)){
myPaint.setColor(Color.BLUE);
images.add(Bitmap.createBitmap(iframeimg));
objectNames.add("iFrame");
xs.add(0F);
ys.add(0F);
}
}
public boolean onTouchEvent(MotionEvent event) {
int action=event.getAction();
if (xs.isEmpty()) {
return true;
}
int pos = xs.size() - 1;
switch(action) {
case MotionEvent.ACTION_DOWN:
xs.set(pos, event.getX());
ys.set(pos, event.getY());
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
xs.set(pos, event.getX());
ys.set(pos, event.getY());
break;
}
return true;
}
public void onDraw(Canvas canvas){
for (int i = 0; i < images.size(); i++) {
float x = xs.get(i);
float y = ys.get(i);
canvas.drawBitmap(images.get(i), x-50, y-50, myPaint);
canvas.drawText(objectNames.get(i), x, y-50, myPaint);
}
invalidate();
}
}

Create signature on image Android?

I'm making an application to create signature on file image. Here, I will load the image file from the memory card to the application and use Canvas Paint can create a signature by hand through the draw.
The problem here is the application requirements for customers to sign in a specific location. My code allows customers can sign in anywhere the customer wants, like paint on the windows. Now, I want to be signed in a specific area only... Help me...
This my code
Main.java
public class Longvan extends Activity implements OnClickListener, OnTouchListener {
ImageView choosenImageView;
Button choosePicture;
Button savePicture;
Bitmap bmp;
Bitmap alteredBitmap;
Canvas canvas;
Paint paint;
Matrix matrix;
float downx = 0;
float downy = 0;
float upx = 0;
float upy = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_longvan);
int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
choosenImageView = (ImageView) this.findViewById(R.id.ChoosenImageView);
choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);
savePicture = (Button) this.findViewById(R.id.SavePictureButton);
savePicture.setOnClickListener(this);
choosePicture.setOnClickListener(this);
choosenImageView.setOnTouchListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_longvan, menu);
return true;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
break;
case MotionEvent.ACTION_MOVE:
upx = event.getX();
upy = event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
choosenImageView.invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
upx = event.getX();
upy = event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
choosenImageView.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == choosePicture) {
Intent choosePictureIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent, 0);
} else if (v == savePicture) {
if (alteredBitmap != null) {
ContentValues contentValues = new ContentValues(3);
contentValues.put(Media.DISPLAY_NAME, "Draw On Me");
Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, contentValues);
try {
OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri);
alteredBitmap.compress(CompressFormat.JPEG, 90, imageFileOS);
Toast t = Toast.makeText(this, "Thank you! Image Saved!", Toast.LENGTH_LONG);
t.show();
} catch (Exception e) {
Log.v("EXCEPTION", e.getMessage());
}
}
}
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {
Uri imageFileUri = intent.getData();
try {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(2);
matrix = new Matrix();
canvas.drawBitmap(bmp, matrix, paint);
choosenImageView.setImageBitmap(alteredBitmap);
choosenImageView.setOnTouchListener(this);
} catch (Exception e) {
Log.v("ERROR", e.toString());
}
}
}
}
How about a specific View for inputting Signatures? Something like this: https://github.com/CoatedMoose/CustomViews/tree/master/library/src/com/coatedmoose/customviews
Then, add this setter for the Bitmap:
public void setImage(Bitmap bitmap) {
this.mBitmap = bitmap;
this.invalidate();
}
Or, if you dont want the applied bitmap as part of your signatureview (use it as background, and not as canvas), replace the onDraw method with this:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
canvas.drawPath(mPath, mPaint);
}
and then just use mSignatureView.setBackgroundResource(R.drawable.background);
Edit:
Just create a Class with the code from coatedMoose, and use it in your layout XML:
<com.example.myapp.gui.views.SignatureView
android:id="#+id/signature"
android:layout_width="match_parent"
android:layout_height="80dp"/>
Somewhere in your code, or even as an XML attribute, you can set the background.
Edit: signatureView class:
package me.other;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* A simple view to capture a path traced onto the screen. Initially intended to be used to captures signatures.
*
* #author Andrew Crichton
* #version 0.1
*/
public class SignatureView extends View {
#SuppressWarnings("unused")
private Path mPath;
private Paint mPaint;
private Paint bgPaint = new Paint(Color.TRANSPARENT);
private Bitmap mBitmap;
private Canvas mCanvas;
private float curX, curY;
private static final int TOUCH_TOLERANCE = 4;
private static final int STROKE_WIDTH = 4;
public SignatureView(Context context) {
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SignatureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setFocusable(true);
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(STROKE_WIDTH);
}
public void setSigColor(int color) {
mPaint.setColor(color);
}
public void setSigColor(int a, int red, int green, int blue) {
mPaint.setARGB(a, red, green, blue);
}
public boolean clearSignature() {
if (mBitmap != null)
createFakeMotionEvents();
if (mCanvas != null) {
mCanvas.drawColor(Color.TRANSPARENT);
mCanvas.drawPaint(bgPaint);
mPath.reset();
invalidate();
}
else {
return false;
}
return true;
}
public Bitmap getImage() {
return this.mBitmap;
}
public void setImage(Bitmap bitmap) {
this.mBitmap = bitmap;
this.invalidate();
}
#Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
int bitmapWidth = mBitmap != null ? mBitmap.getWidth() : 0;
int bitmapHeight = mBitmap != null ? mBitmap.getWidth() : 0;
if (bitmapWidth >= width && bitmapHeight >= height)
return;
if (bitmapWidth < width)
bitmapWidth = width;
if (bitmapHeight < height)
bitmapHeight = height;
Bitmap newBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
Canvas newCanvas = new Canvas();
newCanvas.setBitmap(newBitmap);
if (mBitmap != null)
newCanvas.drawBitmap(mBitmap, 0, 0, null);
mBitmap = newBitmap;
mCanvas = newCanvas;
}
private void createFakeMotionEvents() {
MotionEvent downEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100, MotionEvent.ACTION_DOWN, 1f, 1f ,0);
MotionEvent upEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100, MotionEvent.ACTION_UP, 1f, 1f ,0);
onTouchEvent(downEvent);
onTouchEvent(upEvent);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
canvas.drawPath(mPath, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(x, y);
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
break;
case MotionEvent.ACTION_UP:
touchUp();
break;
}
invalidate();
return true;
}
/**----------------------------------------------------------
* Private methods
**---------------------------------------------------------*/
private void touchDown(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
curX = x;
curY = y;
}
private void touchMove(float x, float y) {
float dx = Math.abs(x - curX);
float dy = Math.abs(y - curY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(curX, curY, (x + curX)/2, (y + curY)/2);
curX = x;
curY = y;
}
}
private void touchUp() {
mPath.lineTo(curX, curY);
if (mCanvas == null) {
mCanvas = new Canvas();
mCanvas.setBitmap(mBitmap);
}
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
}
}
Some random layout XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.mysignatureviewapp.views.SignatureView
android:id="#+id/sign"
android:layout_width="match_parent"
android:layout_height="204dp">
</com.example.mysignatureviewapp.views.SignatureView>
</RelativeLayout>
In the onCreate() method:
private SignatureView sign;
//
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mysignatureviewlayout);
sign = (SignatureView) findViewById(R.id.sign);
sign.setBackgroundResource(R.drawable.mybackgrounddrawable);
}
//get your signature when you press, say, the back button
#Override
public void onBackPressed() {
Bitmap mySignature = sign.getImage();
//do something with bitmap
}
Getting both the background and the signature:
BitmapDrawable mySignature = new BitmapDrawable(sign.getImage());
Drawable background = sign.getBackground();
LayerDrawable ld = new LayerDrawable(new Drawable[] { mySignature, background});

Categories

Resources