Related
I am trying to create an application in which I need to add freehand cropping feature. I used https://github.com/TomiGie/Android-FreeHandCropView this project to integrate it into my project.
Problem is when I am trying to add an image which is captured from the camera seems very big in the view and I can't able to crop the complete image.
Here is the code which I tried.
This is the CropView which has the cropping code.
package com.idoideas.stickermaker.WhatsAppBasedCode;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class CropView extends View implements View.OnTouchListener {
private Paint paint;
private List<Point> points;
boolean flgPathDraw = true;
Point mfirstpoint = null;
boolean bfirstpoint;
Point mlastpoint = null;
Bitmap bitmap;
Context mContext;
public CropView(Context c, Bitmap bitmap) {
super(c);
mContext = c;
this.bitmap = bitmap;
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
this.setOnTouchListener(this);
points = new ArrayList<>();
bfirstpoint = false;
}
public CropView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
points = new ArrayList<>();
bfirstpoint = false;
this.setOnTouchListener(this);
}
public void onDraw(Canvas canvas) {
/*Rect dest = new Rect(0, 0, getWidth(), getHeight());
paint.setFilterBitmap(true); canvas.drawBitmap(bitmap, null, dest, paint);*/
canvas.drawBitmap(bitmap, 0, 0, null);
Path path = new Path();
boolean first = true;
for (int i = 0; i < points.size(); i += 2) {
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (i < points.size() - 1) {
Point next = points.get(i + 1);
path.quadTo(point.x, point.y, next.x, next.y);
} else {
mlastpoint = points.get(i);
path.lineTo(point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (flgPathDraw) {
if (bfirstpoint) {
if (comparepoint(mfirstpoint, point)) {
// points.add(point);
points.add(mfirstpoint);
flgPathDraw = false;
showcropdialog();
} else {
points.add(point);
}
} else {
points.add(point);
}
if (!(bfirstpoint)) {
mfirstpoint = point;
bfirstpoint = true;
}
}
invalidate();
Log.e("Hi ==>", "Size: " + point.x + " " + point.y);
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("Action up*****~~>>>>", "called");
mlastpoint = point;
if (flgPathDraw) {
if (points.size() > 12) {
if (!comparepoint(mfirstpoint, mlastpoint)) {
flgPathDraw = false;
points.add(mfirstpoint);
showcropdialog();
}
}
}
}
return true;
}
private boolean comparepoint(Point first, Point current) {
int left_range_x = current.x - 3;
int left_range_y = current.y - 3;
int right_range_x = current.x + 3;
int right_range_y = current.y + 3;
if ((left_range_x < first.x && first.x < right_range_x)
&& (left_range_y < first.y && first.y < right_range_y)) {
return points.size() >= 10;
} else {
return false;
}
}
public void fillinPartofPath() {
Point point = new Point();
point.x = points.get(0).x;
point.y = points.get(0).y;
points.add(point);
invalidate();
}
public void resetView() {
points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
points = new ArrayList<>();
bfirstpoint = false;
flgPathDraw = true;
invalidate();
}
private void showcropdialog() {
DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
((MainActivity) mContext).cropImage();
break;
case DialogInterface.BUTTON_NEGATIVE:
/*// No button clicked
intent = new Intent(mContext, DisplayCropActivity.class);
intent.putExtra("crop", false); mContext.startActivity(intent);
bfirstpoint = false;*/
resetView();
break;
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage("Do you Want to save Crop or Non-crop image?")
.setPositiveButton("Crop", dialogClickListener)
.setNegativeButton("Non-crop", dialogClickListener).show()
.setCancelable(false);
}
public List<Point> getPoints() {
return points;
}
}
and this is my MainActivity in which I am adding this cropView to do cropping.
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Region;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.idoideas.stickermaker.R;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
private Bitmap mBitmap;
private CropView mSomeView;
private Button continueBtn;
private static final int CROPPED_MARGIN = 100;
private Uri uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Objects.requireNonNull(getSupportActionBar()).setTitle("Crop Image");
mBitmap = DataHolder.getInstance().getBitmap();
mSomeView = new CropView(this, mBitmap);
continueBtn = findViewById(R.id.continueBtn);
LinearLayout layout = findViewById(R.id.layout);
LinearLayout.LayoutParams lp =
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(mSomeView, lp);
continueBtn.setOnClickListener(v -> withoutCropImage());
}
private void withoutCropImage() {
Uri uri = getImageUri(mBitmap, Bitmap.CompressFormat.PNG, 100);
Intent intent = new Intent();
intent.putExtra("uri", uri.toString());
setResult(2, intent);
finish();
}
public void cropImage() {
setContentView(R.layout.activity_picture_preview);
ImageView imageView = findViewById(R.id.image);
Button cancel_action = findViewById(R.id.cancel_action);
Button save_action = findViewById(R.id.save_action);
Bitmap fullScreenBitmap =
Bitmap.createBitmap(mSomeView.getWidth(), mSomeView.getHeight(), mBitmap.getConfig());
Canvas canvas = new Canvas(fullScreenBitmap);
canvas.drawColor(Color.TRANSPARENT);
Path path = new Path();
List<Point> points = mSomeView.getPoints();
for (int i = 0; i < points.size(); i++) {
path.lineTo(points.get(i).x, points.get(i).y);
}
// Cut out the selected portion of the image...
Paint paint = new Paint();
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mBitmap, 0, 0, paint);
// Frame the cut out portion...
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10f);
canvas.drawPath(path, paint);
// Create a bitmap with just the cropped area.
Region region = new Region();
Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
region.setPath(path, clip);
Rect sourceBounds = region.getBounds();
Rect destBounds =
new Rect(CROPPED_MARGIN, CROPPED_MARGIN, sourceBounds.width() + CROPPED_MARGIN,
sourceBounds.height() + CROPPED_MARGIN);
Bitmap croppedBitmap =
Bitmap.createBitmap(sourceBounds.width() + CROPPED_MARGIN * 2,
sourceBounds.height() + CROPPED_MARGIN * 2, mBitmap.getConfig());
canvas.setBitmap(croppedBitmap);
canvas.drawBitmap(fullScreenBitmap, sourceBounds, destBounds, null);
if (croppedBitmap != null) {
uri = getImageUri(croppedBitmap, Bitmap.CompressFormat.PNG, 90);
}
imageView.setImageBitmap(croppedBitmap);
cancel_action.setOnClickListener(v -> {
DataHolder.getInstance().clearDataHolder();
finish();
});
save_action.setOnClickListener(v -> {
if (uri != null && !TextUtils.isEmpty(uri.toString())) {
Intent intent = new Intent();
intent.putExtra("uri", uri.toString());
setResult(2, intent);
finish();
} else {
Toast.makeText(this, "Something went wrong...", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("uri", "");
setResult(2, intent);
finish();
}
});
}
public Uri getImageUri(Bitmap src, Bitmap.CompressFormat format, int quality) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
src.compress(format, quality, os);
String dateCreated = SimpleDateFormat.getDateInstance().format(new Date());
String path = MediaStore.Images.Media.insertImage(getContentResolver(), src, dateCreated, null);
return Uri.parse(path);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
public void onBackPressed() {
DataHolder.getInstance().clearDataHolder();
finish();
super.onBackPressed();
}
}
PLease help me, if anyone knows the solution. Thanks in advance.
So basically the game works like this, Whenever the fire makes contact with the icecream, I want a different icecream to be drawn on the screen. A smaller one that would resemble a "melted" appearance. But whenever the icecream and fire collide, the games ends when it's not suppose to.
This is the code that renders the iceCream
private void renderIceCream(Painter g) {
if (iceCream3) {
g.drawImage(Assets.iceCream3, (int) iceCream.getX(), (int) iceCream.getY(), ICECREAM_WIDTH, IC3_HEIGHT);
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream3 = false;
iceCream2 = true;
}
}
if (iceCream2) {
g.drawImage(Assets.iceCream2, (int) iceCream.getX(), (int) iceCream.getY() + 25, ICECREAM_WIDTH, IC2_HEIGHT);
//
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream2 = false;
iceCream1 = true;
}
}
if (iceCream1) {
g.drawImage(Assets.iceCream1, (int) iceCream.getX(), (int) iceCream.getY() + 50, ICECREAM_WIDTH, IC1_HEIGHT);
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream1 = false;
iceCream.melted();
}
}
}
This is the whole class
package rect.draw.gametest.model.state;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.view.GestureDetector;
import android.view.MotionEvent;
import java.util.ArrayList;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.view.MotionEvent;
import android.widget.Toast;
import rect.draw.gametest.Assets;
import rect.draw.gametest.GameMainActivity;
import rect.draw.gametest.model.Fire;
import rect.draw.gametest.model.IceCream;
import rect.draw.gametest.model.util.Painter;
public class PlayState extends State {
private IceCream iceCream;
private Fire fire;
private int fireX = 400;
private int fireY = 0;
private int cloudX = 0;
private int cloudY = 100;
private float duckDuration = .6f;
private int playerY;
private int playerScore = 0;
private static final int BLOCK_HEIGHT = 50;
private static final int BLOCK_WIDTH = 20;
private int fireSpeed = -200;
private static int ICECREAM_WIDTH = 38;
private static int IC1_HEIGHT = 77;
private static int IC2_HEIGHT= 102;
private static int IC3_HEIGHT = 127;
private static int FIRE_WIDTH = 75;
private static int FIRE_HEIGHT = 75;
public boolean iceCream1,iceCream2,iceCream3,durationEnded;
private float recentTouchY;
#Override
public void init() {
iceCream = new IceCream(160, GameMainActivity.GAME_HEIGHT - 45
- IC3_HEIGHT, ICECREAM_WIDTH, IC3_HEIGHT);
fire = new Fire(10, 10, FIRE_WIDTH, FIRE_HEIGHT);
//cloud = new Cloud(100, 100);
// cloud2 = new Cloud(500, 50);
iceCream2 = true;
// iceCream2 = false;
// iceCream1 = false;
}
#Override
public void update(float delta) {
fire.update(delta, fireSpeed);
iceCream.update(delta);
if (!iceCream.isFrozen()) {
setCurrentState(new GameOverState(playerScore / 100));
}
}
#Override
public void render(Painter g) {
g.setColor(Color.rgb(208, 244, 247));
g.fillRect(0, 0, GameMainActivity.GAME_WIDTH,
GameMainActivity.GAME_HEIGHT);
renderSun(g);
renderClouds(g);
g.drawImage(Assets.grass, 0, 405);
renderIceCream(g);
renderFire(g);
renderScore(g);
}
private void renderScore(Painter g) {
g.setFont(Typeface.SANS_SERIF, 25);
g.setColor(Color.GRAY);
g.drawString("" + playerScore / 100, 20, 30);
}
private void renderFire(Painter g) {
g.drawImage(Assets.gameTestFire, (int) fire.getX(), (int) fire.getY(), FIRE_WIDTH, FIRE_HEIGHT);
if(Rect.intersects(iceCream.getRect(),fire.getRect())){
fire.reset();
}
}
private void renderIceCream(Painter g) {
if (iceCream3) {
g.drawImage(Assets.iceCream3, (int) iceCream.getX(), (int) iceCream.getY(), ICECREAM_WIDTH, IC3_HEIGHT);
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream3 = false;
iceCream2 = true;
}
}
if (iceCream2) {
g.drawImage(Assets.iceCream2, (int) iceCream.getX(), (int) iceCream.getY() + 25, ICECREAM_WIDTH, IC2_HEIGHT);
//
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream2 = false;
iceCream1 = true;
}
}
if (iceCream1) {
g.drawImage(Assets.iceCream1, (int) iceCream.getX(), (int) iceCream.getY() + 50, ICECREAM_WIDTH, IC1_HEIGHT);
if (Rect.intersects(iceCream.getRect(), fire.getRect())) {
iceCream1 = false;
iceCream.melted();
}
}
}
private void renderSun(Painter g) {
g.setColor(Color.rgb(255, 165, 0));
g.fillOval(715, -85, 170, 170);
g.setColor(Color.YELLOW);
g.fillOval(725, -75, 150, 150);
}
private void renderClouds(Painter g) {
g.drawImage(Assets.cloud1, cloudX, cloudY, 100, 60);
cloudX += 4;
if (cloudX > 800) {
cloudX = 0;
}
}
#Override
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
recentTouchY = scaledY;
} else if (e.getAction() == MotionEvent.ACTION_UP) {
if (scaledY - recentTouchY < -50) {
iceCream.jump();
} else if (scaledY - recentTouchY > 50) {
}
}
return true;
}
}
This is the IceCream class
package rect.draw.gametest.model;
import android.graphics.Rect;
public class IceCream {
private static final float ACCEL_GRAVITY = 1800 ;
private static final int JUMP_VELOCITY =-600 ;
private float x,y;
private int width,height;
private Rect rect,ground;
public boolean isFrozen,durationEnded,isGrounded;
private int velY;
public IceCream(float x, float y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
rect = new Rect((int) x, (int) y, (int) x + width, (int) y + height);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
ground = new Rect(0, 405, 0 + 800, 405 + 45);
rect = new Rect();
isFrozen = true;
}
public void update(float delta) {
if (!isGrounded()) {
velY += ACCEL_GRAVITY * delta;
} else {
y = 406 - height;
velY = 0;
}
y += velY * delta;
updateRect();
}
public void jump(){
y -= 10;
velY = JUMP_VELOCITY;
updateRect();
}
public boolean isFrozen(){
return isFrozen;
}
public void melted(){
isFrozen = false;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public void updateRect() {
rect.set((int) x, (int) y, (int) x + width, (int) y + height);
}
public Rect getRect(){
return rect;
}
public boolean isGrounded() {
return Rect.intersects(rect, ground);
}
}
I think the problem can be solved by adding these two else statements:
private void renderIceCream(Painter g) {
if (iceCream3) {
...
}
else if (iceCream2) {
...
}
else if (iceCream1) {
...
}
}
Without the else statements, when iceCream3 is true and there is a collision, iceCream2 becomes true and Java steps into the next if statement where iceCream1 becomes true. With the else statements, this does not happen. If you move away the fire afterwards by calling fire.reset(), your code should work now.
I am making a n app that uses an android phone s accelerometer, I currently have the x value set as the variable mX (that is restricted from 0 - 10) now I have an ImageView widget that I want to rotate left if mX is lower than 5 and rotate right if mX is higher than 5 and reset to horizontal when mX is 5. My problem is that I have tried using animations, matrixs but they don't work . Please help and thanks in advance.
Enjoy this code. If helpful, let me know:
public int getDeviceDefaultOrientation() {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Configuration config = getResources().getConfiguration();
int rotation = windowManager.getDefaultDisplay().getRotation();
if ( ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
return Configuration.ORIENTATION_LANDSCAPE;
} else {
return Configuration.ORIENTATION_PORTRAIT;
}
}
I got a similar example
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class SkySurfaceView extends SurfaceView implements OnTouchListener {
private static final String TAG = SkySurfaceView.class.getSimpleName();
private double viewPortX, viewPortY;
private int starX, starY;
private Bitmap target;
private int targetWidth, targetHeight;
private int vpWidth, vpHeight;
private Matrix skyMatrix, skyMatrix2;
private Matrix skyMatrix3;
private Bitmap star;
private Paint paint;
private Rect touchRect, touchRect2, touchRect3;
public SkySurfaceView(Context context, AttributeSet attr) {
super(context, attr);
viewPortX = viewPortY = 0;
skyMatrix = new Matrix();
skyMatrix2 = new Matrix();
skyMatrix3 = new Matrix();
paint = new Paint();
paint.setStrokeWidth(1);
paint.setDither(true);
paint.setColor(Color.RED);
Options opt = new Options();
opt.inSampleSize = 2;
opt.inScaled = false;
opt.inPreferredConfig = Config.RGB_565;
star = BitmapFactory.decodeResource(getResources(), R.drawable.star,
opt);
touchRect = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect2 = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect3 = new Rect(0, 0, star.getWidth(), star.getHeight());
this.setWillNotDraw(true);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
this.setOnTouchListener(this);
getHolder().setFormat(PixelFormat.RGB_565);
}
public void setTarget(Bitmap b) {
target = b;
targetHeight = target.getHeight();
targetWidth = target.getWidth();
}
public void init() {
this.starX = (int) (vpWidth * Math.random()) + vpWidth;
this.starY = (int) ((vpHeight - star.getHeight()) * Math.random());
Log.i(TAG, "drawn star on " + starX + "," + starY);
Canvas c = new Canvas();
Log.i(TAG,
"target dimension is " + target.getWidth() + "x"
+ target.getHeight());
Bitmap bitmap = Bitmap.createBitmap(target.getWidth(),
target.getHeight(), Config.RGB_565);
c.setBitmap(bitmap);
c.drawBitmap(target, 0, 0, paint);
c.drawBitmap(star, starX, starY, paint);
c.drawBitmap(star, starX - targetWidth, starY, paint);
target.recycle();
setTarget(bitmap);
setWillNotDraw(false);
}
#Override
public boolean performClick() {
super.performClick();
return false;
}
/**
*
* #param x
* - [-1:1]
* #param y
* - [-1:1]
*/
public void setViewPort(double x, double y) {
viewPortX = x;
viewPortY = y;
int tempX = (int) (targetWidth * (viewPortX));
int tempY = (int) (targetHeight * (viewPortY - 1));
tempY = Math.max(tempY, -(targetHeight - vpHeight) / 2);
tempY = Math.min(tempY, +(targetHeight - vpHeight / 2));
Log.i(TAG,
String.format("%d %d , %d %d, %d %d", tempX, tempY, tempX
- targetWidth, tempY, tempX + targetWidth, tempY));
skyMatrix.reset();
skyMatrix.postTranslate(tempX, tempY);
skyMatrix2.reset();
skyMatrix2.postTranslate(tempX - targetWidth, tempY);
skyMatrix3.reset();
skyMatrix3.postTranslate(tempX + targetWidth, tempY);
int xx = (tempX + starX);
while (xx < targetWidth) {
xx += targetWidth;
}
touchRect.offsetTo(xx % targetWidth, (tempY + starY) % targetHeight);
touchRect2.offsetTo(xx % targetWidth - targetWidth, (tempY + starY)
% targetHeight);
touchRect3.offsetTo(xx % targetWidth + targetWidth, (tempY + starY)
% targetHeight);
postInvalidate();
}
public void setViewportSize(int x, int y) {
vpWidth = x;
vpHeight = y;
}
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
c.drawBitmap(target, skyMatrix, paint);
c.drawBitmap(target, skyMatrix2, paint);
c.drawBitmap(target, skyMatrix3, paint);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
float ex = event.getX();
float ey = event.getY();
Log.i(TAG, "touched " + ex + " " + ey);
if (touchRect.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect2.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect3.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
}
return false;
}
public void setListener(OnStarCaptureListener listener) {
this.listener = listener;
}
}
In this class, "target" is the image to be moved according to the viewport. Upon "setViewPort" is called (x and y values from -1 to 1), the view is invalidated and the onDraw() method will draw the image with offset.
I see scale with only 0 written! As in the picture and two strange zeros out of the schema: (GALAXY NEXUS 4.2.1)
As in the example at http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/comment-page-1/#comment-106122%29 this is my custom view:
package com.wikibuyers.barometro;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class Barometro extends View implements SensorEventListener{
private static final String TAG = Barometro.class.getSimpleName();
private Handler handler;
// drawing tools
private RectF rimRect;
private Paint rimPaint;
private Paint rimCirclePaint;
private RectF faceRect;
private Bitmap faceTexture;
private Paint facePaint;
private Paint rimShadowPaint;
private Paint scalePaint;
private RectF scaleRect;
private Paint titlePaint;
private Path titlePath;
private Paint logoPaint;
private Bitmap logo;
private Matrix logoMatrix;
private float logoScale;
private Paint handPaint;
private Path handPath;
private Paint handScrewPaint;
private Paint backgroundPaint;
// end drawing tools
private Bitmap background; // holds the cached static part
// scale configuration
private static final int totalNicks = 100;
private static final float degreesPerNick = 360.0f / totalNicks;
private static final int centerDegree = 40; // the one in the top center (12 o'clock)
private static final int minDegrees = -30;
private static final int maxDegrees = 110;
// hand dynamics -- all are angular expressed in F degrees
private boolean handInitialized = false;
private float handPosition = centerDegree;
private float handTarget = centerDegree;
private float handVelocity = 0.0f;
private float handAcceleration = 0.0f;
private long lastHandMoveTime = -1L;
public Barometro(Context context) {
super(context);
init();
}
public Barometro(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Barometro(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
attachToSensor();
}
#Override
protected void onDetachedFromWindow() {
detachFromSensor();
super.onDetachedFromWindow();
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
Parcelable superState = bundle.getParcelable("superState");
super.onRestoreInstanceState(superState);
handInitialized = bundle.getBoolean("handInitialized");
handPosition = bundle.getFloat("handPosition");
handTarget = bundle.getFloat("handTarget");
handVelocity = bundle.getFloat("handVelocity");
handAcceleration = bundle.getFloat("handAcceleration");
lastHandMoveTime = bundle.getLong("lastHandMoveTime");
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
Bundle state = new Bundle();
state.putParcelable("superState", superState);
state.putBoolean("handInitialized", handInitialized);
state.putFloat("handPosition", handPosition);
state.putFloat("handTarget", handTarget);
state.putFloat("handVelocity", handVelocity);
state.putFloat("handAcceleration", handAcceleration);
state.putLong("lastHandMoveTime", lastHandMoveTime);
return state;
}
#SuppressLint({ "NewApi", "InlinedApi" })
private void init() {
handler = new Handler();
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
initDrawingTools();
}
private String getTitle() {
return "wikibuyers.com";
}
private SensorManager getSensorManager() {
return (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
}
private void attachToSensor() {
SensorManager sensorManager = getSensorManager();
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);
if (sensors.size() > 0) {
Sensor sensor = sensors.get(0);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, handler);
} else {
Log.e(TAG, "No pressure sensor found");
}
}
private void detachFromSensor() {
SensorManager sensorManager = getSensorManager();
sensorManager.unregisterListener(this);
}
private void initDrawingTools() {
rimRect = new RectF(0.1f, 0.1f, 0.9f, 0.9f);
// the linear gradient is a bit skewed for realism
rimPaint = new Paint();
rimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
rimPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f,
Color.rgb(0xf0, 0xf5, 0xf0),
Color.rgb(0x30, 0x31, 0x30),
Shader.TileMode.CLAMP));
rimCirclePaint = new Paint();
rimCirclePaint.setAntiAlias(true);
rimCirclePaint.setStyle(Paint.Style.STROKE);
rimCirclePaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33));
rimCirclePaint.setStrokeWidth(0.005f);
float rimSize = 0.02f;
faceRect = new RectF();
faceRect.set(rimRect.left + rimSize, rimRect.top + rimSize,
rimRect.right - rimSize, rimRect.bottom - rimSize);
faceTexture = BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.plastic);
BitmapShader paperShader = new BitmapShader(faceTexture,
Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Matrix paperMatrix = new Matrix();
facePaint = new Paint();
facePaint.setFilterBitmap(true);
paperMatrix.setScale(1.0f / faceTexture.getWidth(),
1.0f / faceTexture.getHeight());
paperShader.setLocalMatrix(paperMatrix);
facePaint.setStyle(Paint.Style.FILL);
facePaint.setShader(paperShader);
rimShadowPaint = new Paint();
rimShadowPaint.setShader(new RadialGradient(0.5f, 0.5f, faceRect.width() / 2.0f,
new int[] { 0x00000000, 0x00000500, 0x50000500 },
new float[] { 0.96f, 0.96f, 0.99f },
Shader.TileMode.MIRROR));
rimShadowPaint.setStyle(Paint.Style.FILL);
scalePaint = new Paint();
scalePaint.setStyle(Paint.Style.STROKE);
scalePaint.setColor(0x9f004d0f);
scalePaint.setStrokeWidth(0.005f);
scalePaint.setAntiAlias(true);
scalePaint.setTextSize(0.045f);
scalePaint.setTypeface(Typeface.SANS_SERIF);
scalePaint.setTextScaleX(0.8f);
scalePaint.setTextAlign(Paint.Align.CENTER);
float scalePosition = 0.10f;
scaleRect = new RectF();
scaleRect.set(faceRect.left + scalePosition, faceRect.top + scalePosition,
faceRect.right - scalePosition, faceRect.bottom - scalePosition);
titlePaint = new Paint();
titlePaint.setColor(0xaf946109);
titlePaint.setAntiAlias(true);
titlePaint.setTypeface(Typeface.DEFAULT_BOLD);
titlePaint.setTextAlign(Paint.Align.CENTER);
titlePaint.setTextSize(0.05f);
titlePaint.setTextScaleX(0.8f);
titlePath = new Path();
titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f, -180.0f);
logoPaint = new Paint();
logoPaint.setFilterBitmap(true);
logo = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.logo);
logoMatrix = new Matrix();
logoScale = (1.0f / logo.getWidth()) * 0.3f;;
logoMatrix.setScale(logoScale, logoScale);
handPaint = new Paint();
handPaint.setAntiAlias(true);
handPaint.setColor(0xff392f2c);
handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000);
handPaint.setStyle(Paint.Style.FILL);
handPath = new Path();
handPath.moveTo(0.5f, 0.5f + 0.2f);
handPath.lineTo(0.5f - 0.010f, 0.5f + 0.2f - 0.007f);
handPath.lineTo(0.5f - 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.010f, 0.5f + 0.2f - 0.007f);
handPath.lineTo(0.5f, 0.5f + 0.2f);
handPath.addCircle(0.5f, 0.5f, 0.025f, Path.Direction.CW);
handScrewPaint = new Paint();
handScrewPaint.setAntiAlias(true);
handScrewPaint.setColor(0xff493f3c);
handScrewPaint.setStyle(Paint.Style.FILL);
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
// in case there is no size specified
private int getPreferredSize() {
return 300;
}
private void drawRim(Canvas canvas) {
// first, draw the metallic body
canvas.drawOval(rimRect, rimPaint);
// now the outer rim circle
canvas.drawOval(rimRect, rimCirclePaint);
}
private void drawFace(Canvas canvas) {
canvas.drawOval(faceRect, facePaint);
// draw the inner rim circle
canvas.drawOval(faceRect, rimCirclePaint);
// draw the rim shadow inside the face
canvas.drawOval(faceRect, rimShadowPaint);
}
private void drawScale(Canvas canvas) {
canvas.drawOval(scaleRect, scalePaint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
for (int i = 0; i < totalNicks; ++i) {
float y1 = scaleRect.top;
float y2 = y1 - 0.020f;
canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);
if ((i % 5) == 0) {
int value = nickToDegree(i);
if ((value >= minDegrees) && (value <= maxDegrees)) {
String valueString = Integer.toString(value);
canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);
}
}
canvas.rotate(degreesPerNick, 0.5f, 0.5f);
}
canvas.restore();
}
private int nickToDegree(int nick) {
int rawDegree = ((nick < totalNicks / 2) ? nick : (nick - totalNicks)) * 2;
int shiftedDegree = rawDegree + centerDegree;
return shiftedDegree;
}
private float degreeToAngle(float degree) {
return (degree - centerDegree) / 2.0f * degreesPerNick;
}
private void drawTitle(Canvas canvas) {
String title = getTitle();
canvas.drawTextOnPath(title, titlePath, 0.0f,0.0f, titlePaint);
}
private void drawLogo(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(0.5f - logo.getWidth() * logoScale / 2.0f,
0.5f - logo.getHeight() * logoScale / 2.0f);
int color = 0x00000000;
float position = getRelativePressurePosition();
if (position < 0) {
color |= (int) ((0xf0) * -position); // blue
} else {
color |= ((int) ((0xf0) * position)) << 16; // red
}
//Log.d(TAG, "*** " + Integer.toHexString(color));
LightingColorFilter logoFilter = new LightingColorFilter(0xff338822, color);
logoPaint.setColorFilter(logoFilter);
canvas.drawBitmap(logo, logoMatrix, logoPaint);
canvas.restore();
}
private void drawHand(Canvas canvas) {
if (handInitialized) {
float handAngle = degreeToAngle(handPosition);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(handAngle, 0.5f, 0.5f);
canvas.drawPath(handPath, handPaint);
canvas.restore();
canvas.drawCircle(0.5f, 0.5f, 0.01f, handScrewPaint);
}
}
private void drawBackground(Canvas canvas) {
if (background == null) {
Log.w(TAG, "Background not created");
} else {
canvas.drawBitmap(background, 0, 0, backgroundPaint);
}
}
#Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);
float scale = (float) getWidth();
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(scale, scale);
drawLogo(canvas);
drawHand(canvas);
canvas.restore();
if (handNeedsToMove()) {
moveHand();
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG, "Size changed to " + w + "x" + h);
regenerateBackground();
}
private void regenerateBackground() {
// free the old bitmap
if (background != null) {
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(background);
float scale = (float) getWidth();
backgroundCanvas.scale(scale, scale);
drawRim(backgroundCanvas);
drawFace(backgroundCanvas);
drawScale(backgroundCanvas);
drawTitle(backgroundCanvas);
}
private boolean handNeedsToMove() {
return Math.abs(handPosition - handTarget) > 0.001f;
}
private void moveHand() {
if (! handNeedsToMove()) {
return;
}
if (lastHandMoveTime != -1L) {
long currentTime = System.currentTimeMillis();
float delta = (currentTime - lastHandMoveTime) / 1000.0f;
float direction = Math.signum(handVelocity);
if (Math.abs(handVelocity) < 90.0f) {
handAcceleration = 5.0f * (handTarget - handPosition);
} else {
handAcceleration = 0.0f;
}
handPosition += handVelocity * delta;
handVelocity += handAcceleration * delta;
if ((handTarget - handPosition) * direction < 0.01f * direction) {
handPosition = handTarget;
handVelocity = 0.0f;
handAcceleration = 0.0f;
lastHandMoveTime = -1L;
} else {
lastHandMoveTime = System.currentTimeMillis();
}
invalidate();
} else {
lastHandMoveTime = System.currentTimeMillis();
moveHand();
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.values.length > 0) {
float pressureAtm = sensorEvent.values[0]/20;
//Log.i(TAG, "*** Temperature: " + temperatureC);
float pressureMmg = (9.0f / 5.0f) * pressureAtm + 32.0f;
setHandTarget(pressureAtm);
} else {
Log.w(TAG, "Empty sensor event received");
}
}
private float getRelativePressurePosition() {
if (handPosition < centerDegree) {
return - (centerDegree - handPosition) / (float) (centerDegree - minDegrees);
} else {
return (handPosition - centerDegree) / (float) (maxDegrees - centerDegree);
}
}
private void setHandTarget(float pressure) {
if (pressure < minDegrees) {
pressure = minDegrees;
} else if (pressure > maxDegrees) {
pressure = maxDegrees;
}
handTarget = pressure;
handInitialized = true;
invalidate();
}
}
This is focus on drawScale() method:
private void drawScale(Canvas canvas) {
canvas.drawOval(scaleRect, scalePaint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
for (int i = 0; i < totalNicks; ++i) {
float y1 = scaleRect.top;
float y2 = y1 - 0.020f;
canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);
if ((i % 5) == 0) {
int value = nickToDegree(i);
if ((value >= minDegrees) && (value <= maxDegrees)) {
String valueString = Integer.toString(value);
canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);
}
}
canvas.rotate(degreesPerNick, 0.5f, 0.5f);
}
canvas.restore();
}
I am new to android development.. m trying to develop an app to draw a line to follow the finger.. m taking the help of example TouchPaint on Dev Guide .. m getting an error on
events.. getPaintModeForTool(event.getToolType(j), mode) also on event.getHistoricalAxisValue(MotionEvent.AXIS_DISTANCE, j, i)
here is the code
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE
/*|| action == MotionEvent.ACTION_HOVER_MOVE*/) {
final int N = event.getHistorySize();
final int P = event.getPointerCount();
for (int i = 0; i < N; i++) {
for (int j = 0; j < P; j++) {
paint(getPaintModeForTool(event.getToolType(j), mode),
event.getHistoricalX(j, i),
event.getHistoricalY(j, i),
event.getHistoricalPressure(j, i),
event.getHistoricalTouchMajor(j, i),
event.getHistoricalTouchMinor(j, i),
event.getHistoricalOrientation(j, i),
event.getHistoricalAxisValue(MotionEvent.AXIS_DISTANCE, j, i),
event.getHistoricalAxisValue(MotionEvent.AXIS_TILT, j, i));
}
}
what to do guys?
If what you are looking for is just a line to follow the user's touch here is a class I use for a signature capture. It just overrides dispatchTouchEvent(MotionEvent event) and from there it generates a path that follows the user's finger. It has a very nice feature that makes curves the path; you see if the users moves the finger fast the new and last even coordinates are quite far apart (including any historical value associated with the event) and you end up with a jagged path.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SignatureView extends View {
private final String LOG_TAG = this.getClass().getSimpleName();
private float mSignatureWidth = 8f;
private int mSignatureColor = Color.BLACK;
private boolean mCapturing = true;
private Bitmap mSignature = null;
private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
private static final boolean DITHER_FLAG = true;
private Paint mPaint = new Paint();
private Path mPath = new Path();
private final Rect mInvalidRect = new Rect();
private float mX;
private float mY;
private float mCurveEndX;
private float mCurveEndY;
private int mInvalidateExtraBorder = 10;
public SignatureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public SignatureView(Context context) {
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setWillNotDraw(false);
mPaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
mPaint.setColor(mSignatureColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(mSignatureWidth);
mPaint.setDither(DITHER_FLAG);
mPath.reset();
}
#Override
protected void onDraw(Canvas canvas) {
if (mSignature != null) {
canvas.drawBitmap(mSignature, null, new Rect(0, 0, getWidth(),
getHeight()), null);
} else {
canvas.drawPath(mPath, mPaint);
}
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (mCapturing) {
processEvent(event);
Log.d(VIEW_LOG_TAG, "dispatchTouchEvent");
return true;
} else {
return false;
}
}
private boolean processEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(event);
invalidate();
return true;
case MotionEvent.ACTION_MOVE:
Rect rect = touchMove(event);
if (rect != null) {
invalidate(rect);
}
return true;
case MotionEvent.ACTION_UP:
touchUp(event, false);
invalidate();
return true;
case MotionEvent.ACTION_CANCEL:
touchUp(event, true);
invalidate();
return true;
}
return false;
}
private void touchUp(MotionEvent event, boolean b) {
// TODO Auto-generated method stub
}
private Rect touchMove(MotionEvent event) {
Rect areaToRefresh = null;
final float x = event.getX();
final float y = event.getY();
final float previousX = mX;
final float previousY = mY;
areaToRefresh = mInvalidRect;
// start with the curve end
final int border = mInvalidateExtraBorder;
areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border,
(int) mCurveEndX + border, (int) mCurveEndY + border);
float cX = mCurveEndX = (x + previousX) / 2;
float cY = mCurveEndY = (y + previousY) / 2;
mPath.quadTo(previousX, previousY, cX, cY);
// union with the control point of the new curve
areaToRefresh.union((int) previousX - border, (int) previousY - border,
(int) previousX + border, (int) previousY + border);
// union with the end point of the new curve
areaToRefresh.union((int) cX - border, (int) cY - border, (int) cX
+ border, (int) cY + border);
mX = x;
mY = y;
return areaToRefresh;
}
private void touchDown(MotionEvent event) {
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
mPath.moveTo(x, y);
final int border = mInvalidateExtraBorder;
mInvalidRect.set((int) x - border, (int) y - border, (int) x + border,
(int) y + border);
mCurveEndX = x;
mCurveEndY = y;
}
/**
* Erases the signature.
*/
public void clear() {
mSignature = null;
mPath.rewind();
// Repaints the entire view.
invalidate();
}
public boolean isCapturing() {
return mCapturing;
}
public void setIsCapturing(boolean mCapturing) {
this.mCapturing = mCapturing;
}
public void setSignatureBitmap(Bitmap signature) {
mSignature = signature;
invalidate();
}
public Bitmap getSignatureBitmap() {
if (mSignature != null) {
return mSignature;
} else if (mPath.isEmpty()) {
return null;
} else {
Bitmap bmp = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.drawPath(mPath, mPaint);
return bmp;
}
}
public void setSignatureWidth(float width) {
mSignatureWidth = width;
mPaint.setStrokeWidth(mSignatureWidth);
invalidate();
}
public float getSignatureWidth(){
return mPaint.getStrokeWidth();
}
public void setSignatureColor(int color) {
mSignatureColor = color;
}
/**
* #return the byte array representing the signature as a PNG file format
*/
public byte[] getSignaturePNG() {
return getSignatureBytes(CompressFormat.PNG, 0);
}
/**
* #param quality Hint to the compressor, 0-100. 0 meaning compress for small
* size, 100 meaning compress for max quality.
* #return the byte array representing the signature as a JPEG file format
*/
public byte[] getSignatureJPEG(int quality) {
return getSignatureBytes(CompressFormat.JPEG, quality);
}
private byte[] getSignatureBytes(CompressFormat format, int quality) {
Log.d(LOG_TAG, "getSignatureBytes() path is empty: " + mPath.isEmpty());
Bitmap bmp = getSignatureBitmap();
if (bmp == null) {
return null;
} else {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
getSignatureBitmap().compress(format, quality, stream);
return stream.toByteArray();
}
}
}