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.
Related
I'm writing a small Android program in Android Studio that uses MediaProjection to grab a screenshot of the whole screen and then I want to pass that screenshot as a Bitmap to my System Overlay (based on the chatheads example). When the MediaProjection runs and the Imagereader creates the bitmaps, I'm passing the bitmap into a class global variable so I can pass it into my System Overlay service and display it. I'm running into an issue where when the Imageview inside the service tries to read the bmp, I get an error as follows:
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#347a4d5
From my understanding, the garbage collector quickly eats up the passed Bitmap and when the System Overlay tries to grab it, the data is gone. Could someone point me in the right direction on how to keep the bitmap?
Main Activity
package com.example.chatheads;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.media.ImageReader;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class MainActivity extends Activity {
Button startService,stopService;
private static final String TAG = MainActivity.class.getName();
private static final int REQUEST_CODE = 100;
private static String STORE_DIRECTORY;
private static int IMAGES_PRODUCED;
private static final String SCREENCAP_NAME = "screencap";
private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private static MediaProjection sMediaProjection;
private MediaProjectionManager mProjectionManager;
private ImageReader mImageReader;
private Handler mHandler;
private Display mDisplay;
private VirtualDisplay mVirtualDisplay;
private int mDensity;
private int mWidth;
private int mHeight;
private int mRotation;
private OrientationChangeCallback mOrientationChangeCallback;
private Image image = null;
private Bitmap bitmap = null;
Globals sharedData = Globals.getInstance();
public Bitmap getObjectContainer() {
return bitmap;
}
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
#Override
public void onImageAvailable(ImageReader reader) {
FileOutputStream fos = null;
try {
image = mImageReader.acquireLatestImage();
if (image != null) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mWidth;
// create bitmap
bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
sharedData.setScreenshot(bitmap);
// write bitmap to a file
// fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
//bitmap.compress(CompressFormat.JPEG, 100, fos);
IMAGES_PRODUCED++;
//Log.e(TAG, "captured image: " + IMAGES_PRODUCED);
String s = ("captured image: " + String.valueOf(IMAGES_PRODUCED));
Toast toast1 = Toast.makeText(getBaseContext(),s, Toast.LENGTH_SHORT);
toast1.show();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos!=null) {
try {
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bitmap!=null) {
bitmap.recycle();
}
if (image!=null) {
image.close();
}
}
}
}
private class OrientationChangeCallback extends OrientationEventListener {
public OrientationChangeCallback(Context context) {
super(context);
}
#Override
public void onOrientationChanged(int orientation) {
synchronized (this) {
final int rotation = mDisplay.getRotation();
if (rotation != mRotation) {
mRotation = rotation;
try {
// clean up
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
// re-create virtual display depending on device width / height
createVirtualDisplay();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private class MediaProjectionStopCallback extends MediaProjection.Callback {
#Override
public void onStop() {
Log.e("ScreenCapture", "stopping projection.");
mHandler.post(new Runnable() {
#Override
public void run() {
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
if(mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedData.setValue(1);
// call for the projection manager
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
// start projection
Button startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startProjection();
}
});
// stop projection
Button stopButton = (Button)findViewById(R.id.stopButton);
stopButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopProjection();
}
});
// start capture handling thread
new Thread() {
#Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
startService=(Button)findViewById(R.id.startService);
stopService=(Button)findViewById(R.id.stopService);
startService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startService(new Intent(getApplication(), ChatHeadService.class));
}
});
stopService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopService(new Intent(getApplication(), ChatHeadService.class));
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
if (sMediaProjection != null) {
File externalFilesDir = getExternalFilesDir(null);
if (externalFilesDir != null) {
STORE_DIRECTORY = externalFilesDir.getAbsolutePath() + "/screenshots/";
File storeDirectory = new File(STORE_DIRECTORY);
if (!storeDirectory.exists()) {
boolean success = storeDirectory.mkdirs();
if (!success) {
Log.e(TAG, "failed to create file storage directory.");
return;
}
}
} else {
Log.e(TAG, "failed to create file storage directory, getExternalFilesDir is null.");
return;
}
// display metrics
DisplayMetrics metrics = getResources().getDisplayMetrics();
mDensity = metrics.densityDpi;
mDisplay = getWindowManager().getDefaultDisplay();
// create virtual display depending on device width / height
createVirtualDisplay();
// register orientation change callback
mOrientationChangeCallback = new OrientationChangeCallback(this);
if (mOrientationChangeCallback.canDetectOrientation()) {
mOrientationChangeCallback.enable();
}
// register media projection stop callback
sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
}
}
}
/****************************************** UI Widget Callbacks *******************************/
private void startProjection() {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
private void stopProjection() {
mHandler.post(new Runnable() {
#Override
public void run() {
if (sMediaProjection != null) {
sMediaProjection.stop();
}
}
});
}
/****************************************** Factoring Virtual Display creation ****************/
private void createVirtualDisplay() {
// get width and height
Point size = new Point();
mDisplay.getSize(size);
mWidth = size.x;
mHeight = size.y;
// start capture reader
mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
}
}
Service
package com.example.chatheads;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.View;
import android.widget.Toast;
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
WindowManager.LayoutParams params;
Globals sharedData = Globals.getInstance();
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
int h = displayMetrics.heightPixels, w = displayMetrics.widthPixels;
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types
final Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
paint.setAlpha(60);
Rect rect=new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
canvas.drawRect(rect,paint);
paint.setColor(Color.GREEN);
canvas.drawLine(0, 0, 0, h, paint);
canvas.drawLine(0, 0, w, 0, paint);
canvas.drawLine(w, 0, h, w, paint);
canvas.drawLine(0, 0, 0, w, paint);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.face1);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 1000;
//this code is for dragging the chat head
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
boolean isExpanded = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
int n = sharedData.getValue();
//Toast toast1 = Toast.makeText(getBaseContext(),String.valueOf(n), Toast.LENGTH_SHORT);
//toast1.show();
if (isExpanded == true){
chatHead.setImageResource(R.drawable.face1);
isExpanded=false;
params.x = 0;
params.y = 1000;
windowManager.updateViewLayout(chatHead, params);
}
else{
//chatHead.setImageResource(R.drawable.clear);
Bitmap bmp2 = sharedData.getScreenshot();
chatHead.setImageBitmap(bmp2);
isExpanded = true;
params.x = 0;
params.y = 0;
windowManager.updateViewLayout(chatHead, params);
}
return true;
case MotionEvent.ACTION_UP:
//chatHead.setImageResource(R.drawable.test);
return true;
/*case MotionEvent.ACTION_MOVE:
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;*/
}
return false;
}
});
windowManager.addView(chatHead, params);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Globals
package com.example.chatheads;
import android.graphics.Bitmap;
public class Globals {
private static Globals instance = new Globals();
// Getter-Setters
public static Globals getInstance() {
return instance;
}
public static void setInstance(Globals instance) {
Globals.instance = instance;
}
private Globals() {
}
private int testi;
private Bitmap bmpscreenshot;
public Bitmap getScreenshot(){
return bmpscreenshot;
}
public void setScreenshot(Bitmap bmp){
this.bmpscreenshot = bmp;
}
public int getValue() {
return testi;
}
public void setValue(int testi) {
this.testi = testi;
}
}
You seem to be calling bitmap.recycle() too soon. Call it after the service has actually processed the data.
If you want a pass a Bitmap from Activity to service means, convert the bitmap into ByteArray
Intent i = new Intent(this, YourService.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startService(i);
Override onStartCommand in your service
public int onStartCommand (Intent intent, int flags, int startId) {
Bitmap b = BitmapFactory.decodeByteArray(
getIntent().getByteArrayExtra("byteArray"),0,getIntent()
.getByteArrayExtra("byteArray").length);
return null;
}
This is the RoofShape class
package com.view9.stoddart.opengl;
import android.opengl.GLU;
import android.util.Log;
import com.view9.stoddart.model.OpenGlPointObject;
import com.view9.stoddart.model.OpenGlRoofObject;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by view9 on 10/25/15.
*/
public class RoofShape {
ArrayList<CoOrdinatesModel> cordinateList;
List<Short> indicesList;
private FloatBuffer mVertexBuffer = null;
private ShortBuffer mShapeBorderIndicesBuffer = null;
private int mNumOfShapeBorderIndices = 0;
OpenGlRoofObject roofObject;
public RoofShape(OpenGlRoofObject roofObject) {
this.roofObject = roofObject;
setAllBuffers();
}
public void drawShape(GL10 gl) {
// Log.d("#####", "draw called");
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
// Draw all lines
gl.glDrawElements(GL10.GL_LINES, mNumOfShapeBorderIndices,
GL10.GL_UNSIGNED_SHORT, mShapeBorderIndicesBuffer);
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
private void setAllBuffers() {
cordinateList = new ArrayList<>();
cordinateList.add(new CoOrdinatesModel(Float.parseFloat("0.0"), Float.parseFloat("0.0"), Float.parseFloat("0.0")));
for (int pointCount = 0; pointCount < roofObject.getPoinstList().size(); pointCount++) {
OpenGlPointObject pointObject = roofObject.getPoinstList().get(pointCount);
cordinateList.add(new CoOrdinatesModel(pointObject.getxAsis(), pointObject.getyAxis(), pointObject.getzAxis()));
}
/**====================================
* working with the indices for line join
* adding cordinates to indicesList
======================================*/
indicesList = new ArrayList<>();
for (int indicesCount = 0; indicesCount < roofObject.getLinesList().size(); indicesCount++) {
String p = roofObject.getLinesList().get(indicesCount).getPath();
for (String strPoint : p.split(",")) {
//spliting the string and eleminating the prefix string
String prefixStringEleminating = strPoint.substring(1);
Short intPoint = Short.parseShort(prefixStringEleminating);
indicesList.add(intPoint);
}
}
updateVertexListToArray(cordinateList);
updateVerticesListToArray(indicesList);
}
private void updateVerticesListToArray(List<Short> list) {
/**
* For converting indices list to indices array
*/
ArrayList<Short> indicesList = new ArrayList<>();
indicesList.addAll(list);
short[] pointsToJoinList = new short[indicesList.size()];
int indicesCount = 0;
for (short shortIndices : indicesList) {
pointsToJoinList[indicesCount++] = shortIndices;
}
mNumOfShapeBorderIndices = pointsToJoinList.length;
ByteBuffer tbibb = ByteBuffer.allocateDirect(pointsToJoinList.length * 2);
tbibb.order(ByteOrder.nativeOrder());
mShapeBorderIndicesBuffer = tbibb.asShortBuffer();
mShapeBorderIndicesBuffer.put(pointsToJoinList);
mShapeBorderIndicesBuffer.position(0);
}
private void updateVertexListToArray(ArrayList<CoOrdinatesModel> cordinateList) {
/**============================
* working with the vertexes
* adding cordinates to VertexList
===============================*/
List<Float> vList = new ArrayList<>();
int loopSize = cordinateList.size();
for (int i = 0; i < loopSize; i++) {
vList.add(cordinateList.get(i).getxAxis());
vList.add(cordinateList.get(i).getyAxis());
vList.add(cordinateList.get(i).getzAxis());
}
/**
* converting vertex list to array
*/
float[] vertexlist = new float[vList.size()];
int count = 0;
for (float f : vList) {
vertexlist[count++] = f;
}
ByteBuffer vbb = ByteBuffer.allocateDirect(vertexlist.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertexlist);
mVertexBuffer.position(0);
}
public void setFlashingPointTOCordinatelist(GL10 gl, ArrayList<CoOrdinatesModel> flashingPoint) {
cordinateList.addAll(flashingPoint);
mVertexBuffer.clear();
mShapeBorderIndicesBuffer.clear();
updateVertexListToArray(cordinateList);
Short initialPoint = Short.parseShort("0");
Short previousUpdated = Short.parseShort("0");
for (int i = 1; i <= 5; i++) {
String totalNo = (cordinateList.size() + 1) + i + "";
Short indice = Short.parseShort(totalNo);
String str = indice + "";
if (i == 1) {
indicesList.add(Short.parseShort(str));
initialPoint = Short.parseShort(str);
} else if (i == 2) {
indicesList.add(Short.parseShort(str));
previousUpdated = Short.parseShort(str);
} else if (i == 3 || i == 4) {
indicesList.add(previousUpdated);
indicesList.add(Short.parseShort(str));
previousUpdated = Short.parseShort(str);
} else if (i == 5) {
indicesList.add(previousUpdated);
indicesList.add(initialPoint);
}
}
updateVerticesListToArray(indicesList);
drawShape(gl);
}
}
THis is my Renderer class
package com.view9.stoddart.opengl;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import com.view9.stoddart.model.OpenGlRoofObject;
import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;
public class StoddartNewRenderer implements GLSurfaceView.Renderer {
private Context mContext;
public float mAngleX = 0.0f;
public float mAngleY = 0.0f;
public float mAngleZ = 0.0f;
private float mPreviousX;
private float mPreviousY;
private final float TOUCH_SCALE_FACTOR = 0.6f;
private OpenGlRoofObject roofObject;
GL10 glForShape;
RoofShape roofShape;
public StoddartNewRenderer(Context context, OpenGlRoofObject roofObject) {
mContext = context;
this.roofObject = roofObject;
roofShape = new RoofShape(roofObject);
}
public void onDrawFrame(GL10 gl) {
// Log.d("####","draw frame called");
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -3.0f);
gl.glRotatef(mAngleX, 1, 0, 0);
gl.glRotatef(mAngleY, 0, 1, 0);
gl.glRotatef(mAngleZ, 0, 0, 1);
// Set line color to black
gl.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
// gl.glColorMask(true, false, false, true);
roofShape.drawShape(gl);
//testing
glForShape = gl;
}
#Override
public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) {
Log.d("####", "surface created");
gl.glClearColor(1f, 1f, 1f, 1);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_DEPTH_TEST);
// Enabled the vertex buffer for writing and to be used during rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) height = 1;
gl.glViewport(0, 0, width, height);
float aspect = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-aspect, aspect, -1.0f, 1.0f, 1.0f, 0.0f);
Log.d("####", "surface is changed");
}
public void drawSelectedShape(float x, float y) {
ArrayList<CoOrdinatesModel> flashingPoint = new ArrayList<>();
flashingPoint.add(new CoOrdinatesModel(x - 0.1f, y, 0f));
flashingPoint.add(new CoOrdinatesModel(x, y + 0.1f, 0f));
flashingPoint.add(new CoOrdinatesModel(x + 0.1f, y, 0f));
flashingPoint.add(new CoOrdinatesModel(x, y - 0.1f, 0f));
roofShape.setFlashingPointTOCordinatelist(glForShape, flashingPoint);
}
}
This is my GLSurfaceview class
package com.view9.stoddart.opengl;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
/**
* Created by view9 on 10/12/15.
*/
public class StoddartOpenGlSurfaceView extends GLSurfaceView {
StoddartNewRenderer renderer;
public StoddartOpenGlSurfaceView(Context context) {
super(context);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public StoddartOpenGlSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void showRenderer(StoddartNewRenderer renderer) {
this.renderer = renderer;
}
#Override
public boolean onTouchEvent(MotionEvent e) {
// return renderer.onTouchEvent(event);
float x = e.getX() / 100;
float y = e.getY() / 100;
Log.d("position", "x-axis: " + x + " y-axis: " + y);
renderer.drawSelectedShape(x, y);
requestRender();
return true;
}
}
And this is the activity where I've set glsurfaceview
data are fetched from the api which is in xml format I've parsed data well and stored it as a roofobject.
package com.view9.stoddart.activities;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.view9.stoddart.ApiCallConfiguration.ServerConfig;
import com.view9.stoddart.ApiCallConfiguration.WebService;
import com.view9.stoddart.R;
import com.view9.stoddart.fragment.ItemsSelectFragment;
import com.view9.stoddart.model.OpenGlRoofObject;
import com.view9.stoddart.model.SelectItemsDto;
import com.view9.stoddart.opengl.StoddartNewRenderer;
import com.view9.stoddart.opengl.StoddartOpenGlSurfaceView;
import com.view9.stoddart.utills.AppController;
import com.view9.stoddart.utills.Cache;
import com.view9.stoddart.utills.CustomDialogs;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.util.ArrayList;
/**
* Created by view9 on 6/8/15.
*/
public class DrawingFlashingActivity extends BaseActivity {
DrawingFlashingActivity instance = null;
public DrawingFlashingActivity getInstance() {
return instance;
}
OpenGlRoofObject roofObject;
private LinearLayout gridLayout, flashingDiagramLayout;
// StoddartRenderer renderer;
StoddartNewRenderer renderer;
StoddartOpenGlSurfaceView stoddartOpenGlSurfaceView;
Response.Listener<String> response;
Response.ErrorListener errorListener;
Dialog pDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = DrawingFlashingActivity.this;
roofObject = Cache.cachedRoofObject;
iniitilizeUiComponent();
stoddartOpenGlSurfaceView = (StoddartOpenGlSurfaceView) findViewById(R.id.opengl_surface_view);
renderer = new StoddartNewRenderer(getInstance(), roofObject);
stoddartOpenGlSurfaceView.setRenderer(renderer);
stoddartOpenGlSurfaceView.showRenderer(renderer);
gettingServerResponse();
pDialog = CustomDialogs.progressDialog(getInstance(), AppController.LOADING);
}
private void gettingServerResponse() {
response = new Response.Listener<String>() {
#Override
public void onResponse(String s) {
Log.d("response", s);
pDialog.dismiss();
try {
JSONObject nodeObject = new JSONObject(s);
Boolean status = nodeObject.getBoolean("success");
int code = nodeObject.getInt("code");
if (code == 1 && status) {
Cache.FLASHING_TYPE = s;
parseFlashingType(s);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
errorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
if (pDialog.isShowing()) {
pDialog.dismiss();
}
volleyError.printStackTrace();
}
};
}
private void parseFlashingType(String s) {
try {
ArrayList<SelectItemsDto> itemslist = new ArrayList<>();
JSONObject nodeObject = new JSONObject(s);
JSONArray dataArray = nodeObject.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
String type = dataArray.get(i).toString();
itemslist.add(new SelectItemsDto("i", type, false, false));
}
ItemsSelectFragment alertdFragment = new ItemsSelectFragment();
Bundle bundle = new Bundle();
bundle.putString("title", "Choose Flashing Type");
bundle.putBoolean("isSingleSelect", true);
bundle.putSerializable("itemsList", (Serializable) itemslist);
alertdFragment.setArguments(bundle);
alertdFragment.show(getSupportFragmentManager(), "Alert Dialog Fragment");
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public String getToolbarTitle() {
return "Flashing";
}
#Override
public int getResourceLayout() {
return R.layout.layout_flashing_measure_activity;
}
#Override
public int getActivityId() {
return 8;
}
#Override
protected void onPause() {
super.onPause();
stoddartOpenGlSurfaceView.onPause();
}
#Override
protected void onResume() {
super.onResume();
stoddartOpenGlSurfaceView.onResume();
}
private void iniitilizeUiComponent() {
gridLayout = (LinearLayout) findViewById(R.id.l_gridLayout);
gridLayout.setVisibility(View.GONE);
flashingDiagramLayout = (LinearLayout) findViewById(R.id.flashing_diagram_layout);
flashingDiagramLayout.setVisibility(View.VISIBLE);
setListeners();
}
private void setListeners() {
ivTick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Cache.FLASHING_TYPE != "") {
parseFlashingType(Cache.FLASHING_TYPE);
} else {
pDialog.show();
WebService.getFlashingType(response, errorListener, ServerConfig.GET_FLASHING_TYPE_URL);
}
}
});
}
}
Writing these codes I can successfully draw a shape as shown in the diagram. The diagram shown is of a roof. My question is that I want to add a circle on touching the shape; there may be multiple circles, e.g. if I touch on say(1,2,1) co-ordinate, the circle should be added to that point again. If I touch another point, the next circle should be added to that point and so on... This is also shown in the second image.
I've wasted 3 days doing this but didn't find any solutions; what I've tried to do in this code so far is: whenever I touch the view I calculate the value of x and y and passed to this method setFlashingPointTOCordinatelist() which is defined in the RoofShape class.
Any kind of help will be appreciated. And please keep in mind that I am very new to this opengl. I can draw this image here.
And this is the image what I want to do on touch over the shape.
I am learning how to make a spectrum analyzer. I learn from tutorial and here's the code
package com.example.prasetyo.spectrumanalyzer;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import ca.uol.aig.fftpack.RealDoubleFFT;
/*public class SpectrumActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spectrum);
}*/
public class SpectrumActivity extends Activity implements OnClickListener {
public void onClick(View v) {
if (started) {
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}
int frequency = 8000;
int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private RealDoubleFFT transformer;
int blockSize = 256;
Button startStopButton;
boolean started = false;
RecordAudio recordTask;
ImageView imageView;
Bitmap bitmap;
Canvas canvas;
Paint paint;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spectrum);
startStopButton = (Button) this.findViewById(R.id.StartStopButton);
startStopButton.setOnClickListener(this);
transformer = new RealDoubleFFT(blockSize);
imageView = (ImageView) this.findViewById(R.id.ImageView01);
bitmap = Bitmap.createBitmap(256, 100, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
imageView.setImageBitmap(bitmap);
}
/*public void onClick(View v) {
if (started) {
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}*/
private class RecordAudio extends AsyncTask<Void, double[], Void> {
#Override
protected Void doInBackground(Void... params) {
if(isCancelled()){
return null;
}
//try {
int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
try {
audioRecord.startRecording();
}
catch (IllegalStateException e) {
Log.e("Recording Failed", e.toString());
}
while (started) {
int bufferReadResult = audioRecord.read(buffer, 0, blockSize);
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
toTransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit
}
transformer.ft(toTransform);
publishProgress(toTransform);
//Log.e("AudioRecord", "Recording Failed");
//return null;
}
return null;
}
protected void onProgressUpdate(double[]... toTransform) {
canvas.drawColor(Color.BLACK);
for (int i = 0; i < toTransform[0].length; i++) {
int x;
x = i;
int downy = (int) (100 - (toTransform[0][i] * 10));
int upy = 100;
canvas.drawLine(x, downy, x, upy, paint);
imageView.invalidate();
}
}
/*public void onClick(View v) {
if (started) {
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}*/
}
}
Spectrum will show up as line each frequency. If i'm not mistaken, the showed up line appear because of drawLine method. Is there any way to show the frequency in other shape (bar)? Really need help :)
Here's the illustration here is the ilustration https://drive.google.com/open?id=0B3jsXXkRa7pLclFYMDdmUlk5MEU&authuser=0
You can replace canvas.drawLine(x, downy, x, upy, paint); with canvas.drawRect(x * 5, downy, x * 5 + 4, upy, paint);
Canvas.drawRect
I am creating an app in android in which the user creates a drawing by touching the screen and then
save it to storage.
My problem is that sometimes the directory does not created , sometimes the image saves but there are a lot of images saved in directory with black images.
The main file saving operation occurs in getDrawnMessage() method.
Here is my code
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
public class DrawWrite extends View {
float TouchXD = 0, TouchYD = 0, TouchXU = 0, TouchYU = 0, TouchXM = 0,
TouchYM = 0; // Define touch co-ordinates
float x1 = 0, y1 = 0, x2 = 0, y2 = 0; // Define drawing path co-ordinates
float stroke = 2; // Define the message structure width
int i=0;
boolean Move = false, moveD = false, moveU = false; // Define whether the
// touch has occurred or
// not
boolean exp = false;
Paint paint = new Paint(); // Paint object
Path mPath = new Path(); // Define the drawing message path
Context context;
public DrawWrite(Context context) {
super(context);
this.context=context;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
invalidate();
paint.setAntiAlias(true);
if (DrawWriteActivity.clearScreen){
mPath.reset();
DrawWriteActivity.clearScreen = false;
}
cleanButton(canvas);
try {
getDrawnMessage(canvas);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
paint.setColor(Color.parseColor(DrawWriteActivity.colorProvider));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(DrawWriteActivity.strokeProvider);
if (moveD == true) {
x1 = TouchXD;
y1 = TouchYD;
moveD = false;
} else if (Move == true) {
x2 = TouchXD;
y2 = TouchYD;
mPath.moveTo(x1, y1);
mPath.lineTo(x2, y2);
canvas.drawPath(mPath, paint);
x1 = x2;
y1 = y2;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
TouchXD = (float) event.getX();
TouchYD = (float) event.getY();
moveD = true;
break;
case MotionEvent.ACTION_UP:
TouchXU = (float) event.getX();
TouchYU = (float) event.getY();
moveU = true;
break;
case MotionEvent.ACTION_MOVE:
TouchXD = (float) event.getX();
TouchYD = (float) event.getY();
Move = true;
break;
}
return true;
}
public void getDrawnMessage(Canvas canvas) throws FileNotFoundException{
if(exp){
Bitmap bitmap = null;
String root = Environment.getExternalStorageDirectory().toString();
File imgDir = new File(root+"/ChitBak/");
String imgName;
bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
imgDir.mkdirs();
imgName = "img"+i+".jpg";
i++;
File file = new File(imgDir,imgName);
if(file.exists()) file.delete();
FileOutputStream outImg = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, outImg);
exp = false;
Intent in = new Intent(context, MainActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(in);
}
}
private void cleanButton(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.DKGRAY);
canvas.drawRoundRect(new RectF(getWidth() - 100, getHeight() - 70,
getWidth() - 20, getHeight() - 20), 10, 10, paint);
paint.setColor(Color.LTGRAY);
paint.setTextSize(27);
paint.setTextSkewX((float) 0.2);
canvas.drawText("Save", getWidth() - 92, getHeight() - 35, paint);
}
private void isResetRequested() {
if (TouchXD >= (getWidth() - 100) && TouchYD >= getHeight() - 70
&& TouchXD <= (getWidth() - 20) && TouchYD <= getHeight() - 20){
exp = true;
}
}
}
Please help me friends because i don't know how to resolve this.
Thanks in advance.
If you want anything in code then tell me i will provide it.
I think your capture method is wrong.
Saving the View as a Bitmap
Here is a code I'm using to dump an entire view into a Bitmap (this will not save the notification bar nor the navigation bar):
final DisplayMetrics displayMetrics = ApplicationHelper.resources().getDisplayMetrics();
if (displayMetrics == null) {
LogHelper.warning("DisplayMetrics was NULL");
return null;
}
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
view.buildDrawingCache();
final Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
Remember that you can use android.R.id.content to get your entire application's screen space, as a View.
Saving to external storage
With file.mkdirs() your code should work.
I wants to add cropping fature in my ANDROID app. I know there are deafault cropping feature available in gallery but in them only rectangular or circular selection of area is possible. I wants to selected any part of image with free hand and them crop the selected part of image from original image. for example selecting head part of an complete human picture and then crop it. See below what i wants.
BEFORE
AFTER
Please help me and also sugest if any free lib is there.
Thanks
Here is the library I used once:
Android widget for cropping and rotating an image.
To add the Cropper to your application, specify com.edmodo.cropper.CropImageView in your layout XML
<com.edmodo.cropper.CropImageView
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="#+id/CropImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Or you can modify attributes programmatically.
See the WIKI here.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Build.VERSION;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import java.util.ArrayList;
import java.util.List;
public class HandsCropView extends View implements OnTouchListener {
static Bitmap bitmap;
public static List<Point> points;
int C_H_Point;
int C_W_Point;
int DIST = 2;
int D_height;
int D_width;
boolean NutralButton = false;
boolean bfirstpoint = false;
int canvasHeight;
int canvasWidth;
boolean flgPathDraw = true;
Bitmap img;
int img_height;
int img_width;
LayoutParams layoutParams;
Context mContext;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.0f;
Point mfirstpoint = null;
Point mlastpoint = null;
private Paint paint;
Paint tectcolor = new Paint();
private class ScaleListener extends SimpleOnScaleGestureListener {
private ScaleListener() {
}
public boolean onScale(ScaleGestureDetector detector) {
HandsCropView.this.mScaleFactor = HandsCropView.this.mScaleFactor * detector.getScaleFactor();
HandsCropView.this.mScaleFactor = Math.max(0.1f, Math.min(HandsCropView.this.mScaleFactor, 5.0f));
HandsCropView.this.invalidate();
return true;
}
}
public HandsCropView(Context c, Bitmap image) {
super(c);
bitmap = image;
this.img_width = bitmap.getWidth();
this.img_height = bitmap.getHeight();
System.out.println("img_width" + this.img_width + "img_height" + this.img_height);
DisplayMetrics metrics1 = getResources().getDisplayMetrics();
this.D_width = metrics1.widthPixels;
this.D_height = metrics1.heightPixels;
if (this.img_width <= this.D_width) {
this.C_W_Point = this.D_width - this.img_width;
}
if (this.img_height <= this.D_height) {
this.C_H_Point = this.D_height - this.img_height;
}
this.mContext = c;
setFocusable(true);
setFocusableInTouchMode(true);
this.paint = new Paint(1);
this.paint.setStyle(Style.STROKE);
this.paint.setPathEffect(new DashPathEffect(new float[]{10.0f, 20.0f}, 5.0f));
this.paint.setStrokeWidth(5.0f);
this.paint.setColor(-1);
if (VERSION.SDK_INT >= 15) {
setLayerType(1, this.paint);
}
this.paint.setShadowLayer(5.5f, 6.0f, 6.0f, Integer.MIN_VALUE);
this.layoutParams = new LayoutParams(bitmap.getWidth(), bitmap.getHeight());
setOnTouchListener(this);
points = new ArrayList<>();
this.bfirstpoint = false;
this.mScaleDetector = new ScaleGestureDetector(c, new ScaleListener());
}
public HandsCropView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
setFocusable(true);
setFocusableInTouchMode(true);
this.paint = new Paint(1);
this.paint.setStyle(Style.STROKE);
this.paint.setStrokeWidth(2.0f);
setOnTouchListener(this);
points = new ArrayList<>();
this.bfirstpoint = false;
}
public void onDraw(Canvas canvas) {
canvas.scale(this.mScaleFactor, this.mScaleFactor);
canvas.drawBitmap(bitmap, 0.0f, 0.0f, null);
Path path = new Path();
boolean first = true;
for (int i = 0; i < points.size(); i += 2) {
Point point = (Point) points.get(i);
if (first) {
first = false;
path.moveTo((float) point.x, (float) point.y);
} else if (i < points.size() - 1) {
Point next = (Point) points.get(i + 1);
path.quadTo((float) point.x, (float) point.y, (float) next.x, (float) next.y);
} else {
this.mlastpoint = (Point) points.get(i);
path.lineTo((float) point.x, (float) point.y);
}
}
canvas.drawPath(path, this.paint);
}
public boolean onTouch(View view, MotionEvent event) {
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (this.flgPathDraw) {
if (this.bfirstpoint) {
if (comparepoint(this.mfirstpoint, point)) {
points.add(this.mfirstpoint);
this.flgPathDraw = false;
GetValue();
} else if (point.x <= this.img_width && point.y <= this.img_height) {
points.add(point);
}
} else if (point.x <= this.img_width && point.y <= this.img_height) {
points.add(point);
}
if (!this.bfirstpoint) {
this.mfirstpoint = point;
this.bfirstpoint = true;
}
} else {
this.mScaleDetector.onTouchEvent(event);
}
invalidate();
Log.e("Hi ==>", "Size: " + point.x + " " + point.y);
if (event.getAction() == 1) {
this.mlastpoint = point;
if (this.flgPathDraw && points.size() > 12 && !comparepoint(this.mfirstpoint, this.mlastpoint)) {
this.flgPathDraw = false;
points.add(this.mfirstpoint);
GetValue();
}
}
return true;
}
private boolean comparepoint(Point first, Point current) {
int left_range_y = current.y - 3;
int right_range_x = current.x + 3;
int right_range_y = current.y + 3;
if (current.x - 3 >= first.x || first.x >= right_range_x || left_range_y >= first.y || first.y >= right_range_y || points.size() < 10) {
return false;
}
return true;
}
public void fillinPartofPath() {
Point point = new Point();
point.x = ((Point) points.get(0)).x;
point.y = ((Point) points.get(0)).y;
points.add(point);
invalidate();
}
public void resetView() {
points.clear();
this.paint.setColor(-1);
this.paint.setStyle(Style.STROKE);
this.flgPathDraw = true;
invalidate();
}
public static boolean GetValue() {
return true;
}
public boolean getBooleanValue() {
return this.NutralButton;
}
}