Related
I have a out of memory problem here in which i have full screen images being displayed. I want to show images in full screen and I have two buttons to cycle through them to the left or to the right. How can i have the past images be recycled before showing the next to prevent the out of memory exception? or is there an even better way to do so?
here is my class in which i view the image.
public class ImageViewActivity extends Activity
{
private Button btnHome;
private Button btnBack;
private ImageButton btnLeft;
private ImageButton btnRight;
ImageView imageView;
RelativeLayout layout;
int height;
int width;
Bitmap bitmap;
String[] imagesPath;
int position;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
String savedItemClicked;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.imageview_activity);
btnHome = (Button) findViewById(R.id.btnHome);
btnBack = (Button) findViewById(R.id.btnBack);
btnLeft = (ImageButton) findViewById(R.id.leftArrow);
btnRight = (ImageButton) findViewById(R.id.rightArrow);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
width = displayMetrics.widthPixels;
imagesPath = getIntent().getStringExtra("IMAGES").split("\\|");
position = getIntent().getIntExtra("POSITION", 0);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
btnLeft.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 0)
position = 5;
else
position--;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnRight.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 5)
position = 0;
else
position++;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnHome.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), MainMenuActivity.class);
startActivity(ActivitySwitch);
}
});
btnBack.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), AddClientActivity.class);
startActivity(ActivitySwitch);
}
});
imageView.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
});
}
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
thank you for any input and if you need any additional information please feel free to ask!
I would either scale down the image or consider using the Picasso image loading library: http://square.github.io/picasso/
It is also really simply to use and prevents a lot Out of Memory Exceptions.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
it was a lot simpler then i first imagined. i simply added this
bitmap.recycle();
before i declared my bitmap to the new image.
So we're trying to implement an upload image feature in our Android App.
In our registration page, there is an upload button and once pressed, it should redirect to the image gallery and once an image is selected, it should be displayed in the ImageView placed.
Here's an excerpt of the code we're trying to work on.
The issue is, for some images it is correctly displayed but for some, it is either rotated 90 degrees to the right or 180 degrees.
What could be the issue?
public class Register extends AppCompatActivity {
private String mName = "";
private String mUsername = "";
private String mPassword = "";
private String mCompany = "";
private String mContact = "";
private static final int PICK_IMAGE = 100;
ImageView imageView;
Uri imageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Intent recvdIntent = getIntent();
mName = recvdIntent.getStringExtra("NAME");
mUsername = recvdIntent.getStringExtra("USERNAME");
mPassword = recvdIntent.getStringExtra("PASSWORD");
mCompany = recvdIntent.getStringExtra("COMPANY");
mContact = recvdIntent.getStringExtra("CONTACT");
imageView = (ImageView)findViewById(R.id.imageView);
Button btnSubmit = (Button) findViewById(R.id.btn_register);
btnSubmit.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
submitUserData();
Intent launchIntent = new Intent(Register.this, Category.class);
return;
}
}
);
Button upload = (Button) findViewById(R.id.btn_upload);
upload.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
openGallery();
}
});
return;
}
private void openGallery() {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
imageUri = data.getData();
imageView.setImageURI(imageUri);
}
}
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
private void submitUserData() {
EditText edtName = (EditText) findViewById(R.id.edt_name);
EditText edtCompany = (EditText) findViewById(R.id.edt_company);
EditText edtContact = (EditText) findViewById(R.id.edt_contact);
EditText edtUsername = (EditText) findViewById(R.id.edt_username);
EditText edtPassword = (EditText) findViewById(R.id.edt_password);
TaraApp2 app = (TaraApp2) getApplication();
app.saveUserData(edtName.getText().toString(),edtUsername.getText().toString(),
edtPassword.getText().toString(),
edtCompany.getText().toString(),
edtContact.getText().toString() );
finish();
return;
}
}
Uri selectedImageUri = data.getData();
Bitmap bitmap = scaleImage(this,selectedImageUri);
public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
for getting url of the image use this
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
For accessing picture from your gallery you can use the croperino library.
https://android-arsenal.com/details/1/4374
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Croperino.prepareGallery(MainActivity.this);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CroperinoConfig.REQUEST_PICK_FILE:
if (resultCode == Activity.RESULT_OK) {
CroperinoFileUtil.newGalleryFile(data, MainActivity.this);
Croperino.runCropImage(CroperinoFileUtil.getmFileTemp(),
MainActivity.this, true, 1, 1, 0, 0);
}
break;
case CroperinoConfig.REQUEST_CROP_PHOTO:
if (resultCode == Activity.RESULT_OK) {
Uri i = Uri.fromFile(CroperinoFileUtil.getmFileTemp());
ivMain.setImageURI(i);
//Do saving / uploading of photo method here.
//The image file can always be retrieved via
CroperinoFileUtil.getmFileTemp()
}
break;
default:
break;
}
}
I am making a custom camera with face detection, which works successfully.
But I want to add stickers like to the recorded/previewed face.
The location of the eyes is used to properly size and place a hat, glasses, and tie etc. on the Preview.
The Face Detection with the FaceOverlayView
public class FaceOverlayView extends View {
private Paint mPaint;
private Paint mTextPaint;
private int mDisplayOrientation;
private int mOrientation;
private Face[] mFaces;
public FaceOverlayView(Context context) {
super(context);
initialize();
}
private void initialize() {
// We want a green box around the face:
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setAlpha(128);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setDither(true);
mTextPaint.setTextSize(20);
mTextPaint.setColor(Color.GREEN);
mTextPaint.setStyle(Paint.Style.FILL);
}
public void setFaces(Face[] faces) {
mFaces = faces;
invalidate();
}
public void setOrientation(int orientation) {
mOrientation = orientation;
}
public void setDisplayOrientation(int displayOrientation) {
mDisplayOrientation = displayOrientation;
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mFaces != null && mFaces.length > 0) {
Matrix matrix = new Matrix();
Util.prepareMatrix(matrix, false, mDisplayOrientation, getWidth(), getHeight());
canvas.save();
matrix.postRotate(mOrientation);
canvas.rotate(-mOrientation);
RectF rectF = new RectF();
for (Face face : mFaces) {
rectF.set(face.rect);
matrix.mapRect(rectF);
canvas.drawRect(rectF, mPaint);
canvas.drawText("Score " + face.score, rectF.right, rectF.top, mTextPaint);
}
canvas.restore();
}
}
}
I want to add the hat and sunglasses on the preview like a similar in the Play Store, Face 28:
More Info.
I am using for MoodMeSDK to detect the eyes and mouth
The result is 66 Points:
I want put sunglasses, caps, lips, etc. on the face. In the Face28 APK using the SVG file for the face stickers.
I have done something almost similar to this before. So here's how you need to do this: first you need to locate the points relative to the View's Rectangle, for example if you want to place a hat, first pin-point head and relative rectangle of hat based on the CameraView, then place the hat on that coordinate. This is the easy part. The hard part is saving the image. for this you need to save width and length of CameraView and stickers on it and their locations on CameraView. Then you capture the image and get a Bitmap/Drawable. You will most likely get different sizes for produced bitmap than CameraView so you need to re-calculate the coordinate of stickers on this bitmap based on it's w/h to the CameraView and merge stickers on new coordinates and then save it. It is not easy but it is possible as I did it.
Here's my code(in my case sticker was being placed in center of picture):
/**
* Created by Mohammad Erfan Molaei on 9/26/16.
*/
public class CaptureActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback {
private static final String TAG = "CaptureActivity";
private FloatingActionButton takePicture;
private int mCurrentFlash;
private CameraView mCameraView;
private int cameraWidth;
private int cameraHeight;
private int drawableWidth;
private int drawableHeight;
private Handler mBackgroundHandler;
private boolean selectedBrand;
#Override
public void setTheme(int resId) {
selectedBrand = getSharedPreferences(getString(R.string.brand_pref), MODE_PRIVATE)
.getBoolean(getString(R.string.selected_brand), true);
super.setTheme(selectedBrand ? R.style.AppTheme_CaptureTheme : R.style.AppTheme_CaptureTheme2);
}
private String itemID = null;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture:
if (mCameraView != null) {
mCameraView.takePicture();
takePicture.setEnabled(false);
}
break;
case R.id.scale_up_btn:
scaleUpImage();
break;
case R.id.scale_down_btn:
scaleDownImage();
break;
}
}
};
private void scaleUpImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
/*Log.e(TAG, "scaleDownImage: oldWidth: " + imageView.getLayoutParams().width +
", oldHeight: " + imageView.getLayoutParams().height);
Log.e(TAG, "scaleDownImage: newWidth2B: " + (imageView.getLayoutParams().width * 1.1f) +
", newHeight2B: " + ((1.1f * imageView.getLayoutParams().width) *
imageView.getLayoutParams().height /
imageView.getLayoutParams().width));
Log.e(TAG, "cameraWidth: " + mCameraView.getLayoutParams().width );
sdasd*/
if (imageView.getWidth() * 1.1f > mCameraView.getWidth() ||
((1.1f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth()) > mCameraView.getHeight())
return;
imageView.getLayoutParams().height = (int) ((1.1f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth());
imageView.getLayoutParams().width = (int) (imageView.getWidth() * 1.1f);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
}
}
private void scaleDownImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
if (imageView.getWidth() * 0.9f > mCameraView.getWidth() ||
((0.9f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth()) > mCameraView.getHeight())
return;
imageView.getLayoutParams().height = (int) ((0.9f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth());
imageView.getLayoutParams().width = (int) (imageView.getWidth() * 0.9f);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
}
}
private void rotateImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
/*Drawable mDrawable = imageView.getDrawable();
int mDrawableWidth = mDrawable.getBounds().width();
int mDrawableHeight = mDrawable.getBounds().height();*/
int newWidth = imageView.getHeight();
int newHeight = imageView.getWidth();
float scaleFactor = 1;
/*Log.e(TAG, "rotateImage: prevWidth: " + newHeight + ", prevHeight: " + newWidth);
Log.e(TAG, "rotateImage: cameraWidth: " + mCameraView.getWidth() );*/
if (newWidth > mCameraView.getWidth() ) {
scaleFactor = (float)newWidth / (float)mCameraView.getWidth();
newWidth = mCameraView.getWidth();
newHeight *= scaleFactor;
} else if (newHeight > mCameraView.getHeight() ) {
scaleFactor = (float)newHeight / (float)mCameraView.getHeight();
newHeight = mCameraView.getHeight();
newWidth *= scaleFactor;
}
Log.e(TAG, "rotateImage: scaleFactor: " + scaleFactor);
imageView.setRotation(imageView.getRotation() + 90);
imageView.getLayoutParams().height = newHeight;
imageView.getLayoutParams().width = newWidth;
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
//imageView.setImageDrawable(getRotatedDrawable(imageView));
/*Bitmap bitmapOrg = drawableToBitmap(imageView.getDrawable());
// createa matrix for the manipulation
Matrix matrix = imageView.getImageMatrix();
int width = bitmapOrg.getWidth();
int height = bitmapOrg.getHeight();
// rotate the Bitmap
matrix.postRotate(90);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(getResources(), resizedBitmap);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);*/
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture);
mCameraView = (CameraView) findViewById(R.id.camera);
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
takePicture = (FloatingActionButton) findViewById(R.id.take_picture);
if (takePicture != null) {
takePicture.setOnClickListener(mOnClickListener);
}
/*if (selectedBrand) {
assert takePicture != null;
takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent));
findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary));
} else {
assert takePicture != null;
takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent2));
findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary2));
}*/
findViewById(R.id.scale_up_btn).setOnClickListener(mOnClickListener);
findViewById(R.id.scale_down_btn).setOnClickListener(mOnClickListener);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras != null) {
itemID = extras.getString("id", null);
}
} else {
itemID = (String) savedInstanceState.getSerializable("id");
}
if( itemID != null ) {
new AsyncImageLoader().execute(itemID);
} else {
this.finish();
return;
}
ViewTreeObserver viewTreeObserver = mCameraView.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
/*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mCameraView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mCameraView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}*/
cameraWidth = dp2px(mCameraView.getWidth());
cameraHeight = dp2px(mCameraView.getHeight());
Log.e("camB4Action", "" + cameraWidth + ", " + cameraHeight);
}
});
}
}
#Override
protected void onResume() {
super.onResume();
mCameraView.start();
}
#Override
protected void onPause() {
mCameraView.stop();
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
}
private Drawable getFlippedDrawable(final Drawable d) {
final Drawable[] arD = { d };
return new LayerDrawable(arD) {
#Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.scale(-1, 1, d.getBounds().width() / 2, d.getBounds().height() / 2);
super.draw(canvas);
canvas.restore();
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.camera, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.switch_flash:
if (mCameraView != null) {
mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
item.setTitle(FLASH_TITLES[mCurrentFlash]);
item.setIcon(FLASH_ICONS[mCurrentFlash]);
mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
}
break;
case R.id.switch_camera:
if (mCameraView != null) {
int facing = mCameraView.getFacing();
mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
CameraView.FACING_BACK : CameraView.FACING_FRONT);
}
break;
case R.id.mirror_image:
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
imageView.setImageDrawable(getFlippedDrawable(imageView.getDrawable()));
imageView.requestLayout();
}
break;
case R.id.rotate_image:
if (mCameraView != null) {
rotateImage();
}
break;
}
return false;
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
public static Bitmap scaleBitmap(Bitmap bitmap, int wantedWidth, int wantedHeight, float rotation) {
Log.e(TAG, "scaleBitmap: bitmapWidth: " + bitmap.getWidth() + ", bitmapHeight: " + bitmap.getHeight() );
Log.e(TAG, "scaleBitmap: wantedWidth: " +
((rotation % 180 == 90) ? wantedHeight : wantedWidth) +
", wantedHeight: " + ((rotation % 180 == 90) ? wantedWidth : wantedHeight) );
Bitmap output = Bitmap.createBitmap(
(rotation % 180 == 90) ? wantedHeight : wantedWidth,
(rotation % 180 == 90) ? wantedWidth : wantedHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Matrix m = new Matrix();
m.setScale((float)
((rotation % 180 == 90) ? wantedHeight : wantedWidth) / bitmap.getWidth(),
(float) ((rotation % 180 == 90) ? wantedWidth : wantedHeight) / bitmap.getHeight());
canvas.drawBitmap(bitmap, m, new Paint());
return output;
/*Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()),
new RectF(0, 0, (rotation % 180 == 90) ? wantedHeight : wantedWidth,
(rotation % 180 == 90) ? wantedWidth : wantedHeight), Matrix.ScaleToFit.CENTER);
return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);*/
}
private CameraView.Callback mCallback
= new CameraView.Callback() {
ProgressiveToast progressiveToast;
#Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
#Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
#Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
/*TastyToast.makeText(cameraView.getContext(), getString(R.string.pic_being_saved),
TastyToast.LENGTH_LONG, TastyToast.INFO);*/
progressiveToast = ProgressiveToast.getInstance();
progressiveToast.show(CaptureActivity.this, getString(R.string.in_action_be_patient), -1);
getBackgroundHandler().post(new Runnable() {
#Override
public void run() {
mCameraView.stop();
// This demo app saves the taken picture to a constant file.
// $ adb pull /sdcard/Android/data/com.google.android.cameraview.demo/files/Pictures/picture.jpg
SizeAwareImageView imageView = ((SizeAwareImageView) mCameraView.findViewById(R.id.mImageView));
Bitmap imageBitmap =
drawableToBitmap(imageView.getDrawable());
Matrix matrix = new Matrix();
float rotation = mCameraView.findViewById(R.id.mImageView).getRotation();
matrix.postRotate(rotation);
//matrix.postScale(drawableWidth, drawableHeight);
/*
matrix.setScale((float)
((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getWidth(),
(float) ((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getHeight());*/
Log.e(TAG, "rotation: " + rotation);
imageBitmap = Bitmap.createBitmap(imageBitmap , 0, 0,
imageBitmap.getWidth(), imageBitmap.getHeight(), matrix, true);
imageBitmap = scaleBitmap(imageBitmap, drawableWidth, drawableHeight, rotation);
Bitmap cameraBmp = BitmapFactory.decodeByteArray(data, 0, data.length);
cameraBmp = fixOrientation(cameraBmp);
File dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + getString(R.string.gallery_folder_name) +
(selectedBrand ? getString(R.string.ibr_eng) :
getString(R.string.tiyaco_eng)));
dir.mkdirs();
File file = new File(dir.getAbsolutePath() ,
Long.toString(Calendar.getInstance().getTimeInMillis()) + ".jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
OutputStream os = null;
InputStream is = overlayBitmapToCenter(cameraBmp, imageBitmap, rotation);
byte[] buffer = new byte[10 * 1024];
int n = 0;
try {
os = new FileOutputStream(file);
while (-1 != (n = is.read(buffer))) {
os.write(buffer, 0, n);
}
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mCameraView != null)
try {
mCameraView.start();
} catch (Exception ignored){}
if (takePicture != null) {
takePicture.setEnabled(true);
}
progressiveToast.dismiss();
TastyToast.makeText(getApplicationContext(), getString(R.string.picture_taken),
TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
}
});
}
}
}
});
}
};
public Bitmap fixOrientation(Bitmap mBitmap) {
if (mBitmap.getWidth() > mBitmap.getHeight()) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
return Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
}
return mBitmap;
}
private int dp2px(int dp) {
return (int)((dp * getResources().getDisplayMetrics().density) + 0.5);
}
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public ByteArrayInputStream overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2, float rotation) {
float alpha = (float)cameraWidth / (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth);
float beta = (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth) /
(float)((rotation % 180 == 90) ? drawableWidth : drawableHeight);
int bitmap1Width = bitmap1.getWidth();
int bitmap1Height = bitmap1.getHeight();
Bitmap scaledImg = Bitmap.createScaledBitmap(bitmap2, (int)((float)bitmap1Width / alpha),
(int)(((float)bitmap1Width / alpha) / beta), false);
int bitmap2Width = scaledImg.getWidth();
int bitmap2Height = scaledImg.getHeight();
/*Log.e("cam", "" + bitmap1Width + ", " + bitmap1Height );
Log.e("img", "" + bitmap2Width + ", " + bitmap2Height );
Log.e("alpha", "" + alpha );
Log.e("beta", "" + beta );*/
float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);
Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
Canvas canvas = new Canvas(overlayBitmap);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(scaledImg, marginLeft, marginTop, null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
overlayBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return new ByteArrayInputStream(stream.toByteArray());
}
private class AsyncImageLoader extends AsyncTask<String, Void, BitmapDrawable>{
private Realm realm;
private ProductModel product;
#Override
protected BitmapDrawable doInBackground(String... itemIds) {
realm = Realm.getDefaultInstance();
product = realm.where(ProductModel.class)
.equalTo("isIbr", selectedBrand)
.equalTo("id", itemIds[0])
.findFirst();
byte[] image = product.getImage();
product = null;
realm.close();
BitmapDrawable mDrawable = new BitmapDrawable(getResources(), BitmapFactory
.decodeByteArray(image, 0, image.length));
int mDrawableHeight = mDrawable.getIntrinsicHeight();
int mDrawableWidth = mDrawable.getIntrinsicWidth();
int valueInPixels = (int) getResources().getDimension(R.dimen.video_view_dimen);
mDrawable.setBounds(0, 0, valueInPixels, valueInPixels * mDrawableHeight / mDrawableWidth);
return mDrawable;
}
#Override
protected void onPostExecute(BitmapDrawable drawable) {
super.onPostExecute(drawable);
LayoutInflater vi = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View v = vi.inflate(R.layout.imageview_product, null);
((SizeAwareImageView)v).setImageDrawable(drawable);
ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.e(TAG, "onGlobalLayout: updating sizes for drawable");
float[] sizez = ((SizeAwareImageView) v).getImageWidthAndHeight();
/*if (v.getRotation() == 90 || v.getRotation() == 270) {
drawableWidth = dp2px(sizez[1]);
drawableHeight = dp2px(sizez[0]);
} else {
drawableWidth = dp2px(sizez[0]);
drawableHeight = dp2px(sizez[1]);
}*/
drawableWidth = dp2px((int) sizez[0]);
drawableHeight = dp2px((int) sizez[1]);
/*Log.e("picB4Action", "" + drawableWidth + ", " + drawableHeight);*/
}
});
}
int px = (int) (getResources().getDimension(R.dimen.video_view_dimen)/* /
getResources().getDisplayMetrics().density*/);
mCameraView.addView(v, new FrameLayout.LayoutParams(px, px, Gravity.CENTER));
}
}
}
SizeAwareImageView.java :
public class SizeAwareImageView extends ImageView {
public SizeAwareImageView(Context context) {
super(context);
}
public SizeAwareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SizeAwareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SizeAwareImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
}
public float[] getMatrixValues() {
float[] f = new float[9];
getImageMatrix().getValues(f);
return f;
}
public float[] getImageWidthAndHeight() {
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
//Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
return new float[] {actW, actH, scaleX, scaleY};
}
}
I have an image which a user can paint on in my android application. I decided to add an undo button to it so the user can cancel mistakes. I made it so that when the user draws on the screen, it saves the bitmap to an array. Then when the undo button is pressed, it changes the image to the last bitmap in the array. However, this just keeps setting the image to whatever the current image is (i.e. it doesn't change it at all).
public class edit extends AppCompatActivity implements View.OnClickListener {
float MoveX,MoveY,DownY,DownX,UpY=0,UpX ;
List<Bitmap> undos = new ArrayList<Bitmap>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
final ImageButton btn2 = (ImageButton) findViewById(R.id.imageButton2);
btn2.setOnClickListener(this);
final Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setOnClickListener(this);
final RelativeLayout ViewX = (RelativeLayout) findViewById(R.id.RLXV);
ViewTreeObserver vto = ViewX.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewX.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Intent intent7 = getIntent();
String bitmapXY = (String) intent7.getExtras().get("BitmapImage");
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/" + bitmapXY,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
HttpURLConnection connection = null;
try {
int ViewWidth = ViewX.getMeasuredWidth();
JSONObject photos = response.getJSONObject();
JSONArray linkY = photos.optJSONArray("images");
final JSONObject linkO = linkY.optJSONObject(0);
final String link2 = linkO.optString("source");
URL LINKF = new URL(link2);
connection = (HttpURLConnection) LINKF.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
float HH = (float) bitmap.getHeight();
float WW = (float) bitmap.getWidth();
float ViewWidthX = (float) ViewWidth;
float height = (HH / WW) * ViewWidthX;
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
undos.add(bitmapF);
image1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Display d = getWindowManager().getDefaultDisplay();
float dw = d.getWidth();
float dh = d.getHeight();
float x = event.getX();
float y = event.getY();
float r = 2;
Bitmap BTX = ((BitmapDrawable)image1.getDrawable()).getBitmap();
Canvas canvas = new Canvas(BTX);
canvas.drawBitmap(BTX,0,0,null);
Paint paint1 = new Paint();
int bg1 = buttonchoose.getDrawingCacheBackgroundColor();
ColorDrawable buttonColor = (ColorDrawable) buttonchoose.getBackground();
int bg2 =buttonColor.getColor();
paint1.setColor(bg2);
paint1.setShadowLayer(5, 2, 2, bg2);
paint1.setStrokeWidth(20);
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
DownY = event.getY();
DownX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
MoveY = event.getY();
MoveX = event.getX();
canvas.drawLine(DownX, DownY, MoveX, MoveY, paint1);
image1.invalidate();
DownX = MoveX;
DownY=MoveY;
break;
case MotionEvent.ACTION_UP:
UpY = event.getY();
UpX = event.getX();
canvas.drawLine(DownX, DownY, UpX, UpY, paint1);
image1.invalidate();
Bitmap BTXYZ = ((BitmapDrawable)image1.getDrawable()).getBitmap();
break;
}
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "images");
request.setParameters(parameters);
request.executeAsync();
}
});
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.buttonchoose:
final ColorPicker cp = new ColorPicker(edit.this, 0, 0, 0);
/* Show color picker dialog */
cp.show();
/* On Click listener for the dialog, when the user select the color */
Button okColor = (Button) cp.findViewById(R.id.okColorButton);
okColor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* You can get single channel (value 0-255) */
int selectedColorR = cp.getRed();
int selectedColorG = cp.getGreen();
int selectedColorB = cp.getBlue();
/* Or the android RGB Color (see the android Color class reference) */
int selectedColorRGB = cp.getColor();
Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setText("");
buttonchoose.setBackgroundColor(selectedColorRGB);
cp.dismiss();
}
});
break;
case R.id.imageButton2:
int newImage = undos.size();
Log.e("Lenght of Array",""+newImage);
if(newImage >=1) {
Bitmap newImage2 = undos.get(newImage-2);
ImageView IMGXV = (ImageView) findViewById(R.id.image1);
IMGXV.setImageBitmap(newImage2);
undos.remove(newImage-1);
}
break;
}
}
}
Try this exact code -
case R.id.imageButton2:
if(undos.size() > 0) {
Bitmap newImage2 = undos.remove(undos.size() - 1);
ImageView IMGXV = (ImageView) findViewById(R.id.image1);
IMGXV.setImageBitmap(newImage2);
}
break;
EDIT Added an extra line in onGlobalLayout(), try this -
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
//The extra line before adding bitmap to arraylist.
Bitmap bitmapFcopy = bitmapFcopy.copy(bitmapFcopy.getConfig(), true);
undos.add(bitmapFcopy);
EDIT 2
public class edit extends AppCompatActivity implements View.OnClickListener {
//Declare the imageview here and access this everywhere.
ImageView image1;
float MoveX,MoveY,DownY,DownX,UpY=0,UpX ;
List<Bitmap> undos = new ArrayList<Bitmap>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
//Get the reference here
image1 = (ImageView) findViewById(R.id.image1);
final ImageButton btn2 = (ImageButton) findViewById(R.id.imageButton2);
btn2.setOnClickListener(this);
final Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setOnClickListener(this);
final RelativeLayout ViewX = (RelativeLayout) findViewById(R.id.RLXV);
ViewTreeObserver vto = ViewX.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewX.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Intent intent7 = getIntent();
String bitmapXY = (String) intent7.getExtras().get("BitmapImage");
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/" + bitmapXY,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
HttpURLConnection connection = null;
try {
int ViewWidth = ViewX.getMeasuredWidth();
JSONObject photos = response.getJSONObject();
JSONArray linkY = photos.optJSONArray("images");
final JSONObject linkO = linkY.optJSONObject(0);
final String link2 = linkO.optString("source");
URL LINKF = new URL(link2);
connection = (HttpURLConnection) LINKF.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
float HH = (float) bitmap.getHeight();
float WW = (float) bitmap.getWidth();
float ViewWidthX = (float) ViewWidth;
float height = (HH / WW) * ViewWidthX;
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
//Remove from here and declare this in onCreate() and don't make it final
//final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
undos.add(bitmapF);
image1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Display d = getWindowManager().getDefaultDisplay();
float dw = d.getWidth();
float dh = d.getHeight();
float x = event.getX();
float y = event.getY();
float r = 2;
Bitmap BTX = ((BitmapDrawable)image1.getDrawable()).getBitmap();
Canvas canvas = new Canvas(BTX);
canvas.drawBitmap(BTX,0,0,null);
Paint paint1 = new Paint();
int bg1 = buttonchoose.getDrawingCacheBackgroundColor();
ColorDrawable buttonColor = (ColorDrawable) buttonchoose.getBackground();
int bg2 =buttonColor.getColor();
paint1.setColor(bg2);
paint1.setShadowLayer(5, 2, 2, bg2);
paint1.setStrokeWidth(20);
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
DownY = event.getY();
DownX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
MoveY = event.getY();
MoveX = event.getX();
canvas.drawLine(DownX, DownY, MoveX, MoveY, paint1);
image1.invalidate();
DownX = MoveX;
DownY=MoveY;
break;
case MotionEvent.ACTION_UP:
UpY = event.getY();
UpX = event.getX();
canvas.drawLine(DownX, DownY, UpX, UpY, paint1);
image1.invalidate();
Bitmap BTXYZ = ((BitmapDrawable)image1.getDrawable()).getBitmap();
break;
}
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "images");
request.setParameters(parameters);
request.executeAsync();
}
});
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.buttonchoose:
final ColorPicker cp = new ColorPicker(edit.this, 0, 0, 0);
/* Show color picker dialog */
cp.show();
/* On Click listener for the dialog, when the user select the color */
Button okColor = (Button) cp.findViewById(R.id.okColorButton);
okColor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* You can get single channel (value 0-255) */
int selectedColorR = cp.getRed();
int selectedColorG = cp.getGreen();
int selectedColorB = cp.getBlue();
/* Or the android RGB Color (see the android Color class reference) */
int selectedColorRGB = cp.getColor();
Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setText("");
buttonchoose.setBackgroundColor(selectedColorRGB);
cp.dismiss();
}
});
break;
case R.id.imageButton2:
int newImage = undos.size();
Log.e("Lenght of Array",""+newImage);
if(newImage >=1) {
Bitmap newImage2 = undos.get(newImage-2);
//Don't take reference again here
//ImageView IMGXV = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(newImage2);
undos.remove(newImage-1);
}
break;
}
}
}
hey i tried the kikose/swipeable-cards library but its performance isnt good(lags even on nexus 5 ). i tried to change the mMaxVisible in the cardContainer class from 3 to 2 the performance improved a little but still lags so i changes it to 1 and the performance looked very card on the first. after i swiped the first card the second isnt swipeable . the mTopCard in the cardcontainer class is null . how can i fix this or improve performance in others way maybe ?
here is the cardcontainer class :
public class CardContainer extends AdapterView<ListAdapter> {
public static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private static final double DISORDERED_MAX_ROTATION_RADIANS = Math.PI / 64;
private int mNumberOfCards = -1;
Context context;
private final DataSetObserver mDataSetObserver = new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
clearStack();
ensureFull();
}
#Override
public void onInvalidated() {
super.onInvalidated();
clearStack();
}
};
private final Random mRandom = new Random();
private final Rect boundsRect = new Rect();
private final Rect childRect = new Rect();
private final Matrix mMatrix = new Matrix();
//TODO: determine max dynamically based on device speed
private int mMaxVisible =2;
private GestureDetector mGestureDetector;
private int mFlingSlop;
private Orientation mOrientation;
private ListAdapter mListAdapter;
private float mLastTouchX;
private float mLastTouchY;
private View mTopCard;
private int mTouchSlop;
private int mGravity;
private int mNextAdapterPosition;
private boolean mDragging;
private boolean animating;
int index;
Profile cardModel;
public CardContainer(Context context) {
super(context);
this.context = context;
setOrientation(Orientation.Disordered);
setGravity(Gravity.TOP);
init();
animating = false;
}
public CardContainer(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initFromXml(attrs);
init();
}
public CardContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initFromXml(attrs);
init();
}
private void init() {
ViewConfiguration viewConfiguration = ViewConfiguration
.get(getContext());
mFlingSlop = viewConfiguration.getScaledMinimumFlingVelocity();
mTouchSlop = viewConfiguration.getScaledTouchSlop();
mGestureDetector = new GestureDetector(getContext(),
new GestureListener());
}
private void initFromXml(AttributeSet attr) {
TypedArray a = getContext().obtainStyledAttributes(attr,
R.styleable.CardContainer);
setGravity(a.getInteger(R.styleable.CardContainer_android_gravity,
Gravity.TOP));
int orientation = a
.getInteger(R.styleable.CardContainer_orientation, 1);
setOrientation(Orientation.fromIndex(orientation));
index = 0;
a.recycle();
}
#Override
public ListAdapter getAdapter() {
return mListAdapter;
}
#Override
public void setAdapter(ListAdapter adapter) {
index = 0;
if (mListAdapter != null)
mListAdapter.unregisterDataSetObserver(mDataSetObserver);
clearStack();
mTopCard = null;
mListAdapter = adapter;
mNextAdapterPosition = 0;
adapter.registerDataSetObserver(mDataSetObserver);
ensureFull();
Log.e("GETCHILD CARD CONT","getChildAt(getChildCount() - 1)==================="+getChildAt(getChildCount() - 1));
Log.e("GETCHILD CARD CONT","getChildCount()==================="+getChildCount());
if (getChildCount() != 0) {
mTopCard = getChildAt(getChildCount() - 1);
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
}
mNumberOfCards = getAdapter().getCount();
requestLayout();
((Profile)adapter.getItem(0)).getOnCardDimissedListener().initialiseCard();
}
private void ensureFull() {
while (mNextAdapterPosition < mListAdapter.getCount() && getChildCount() < mMaxVisible) {
View view = mListAdapter.getView(mNextAdapterPosition, null, this);
view.setLayerType(LAYER_TYPE_SOFTWARE, null);
if(mOrientation == Orientation.Disordered) {
view.setRotation(getDisorderedRotation());
}
addViewInLayout(view, 0, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
mListAdapter.getItemViewType(mNextAdapterPosition)), false);
requestLayout();
mNextAdapterPosition += 1;
}
}
private void clearStack() {
removeAllViewsInLayout();
mNextAdapterPosition = 0;
mTopCard = null;
}
public Orientation getOrientation() {
return mOrientation;
}
public void setOrientation(Orientation orientation) {
if (orientation == null)
throw new NullPointerException("Orientation may not be null");
if(mOrientation != orientation) {
this.mOrientation = orientation;
if(orientation == Orientation.Disordered) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setRotation(getDisorderedRotation());
}
}
else {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setRotation(0);
}
}
requestLayout();
}
}
private float getDisorderedRotation() {
return (float) Math.toDegrees(mRandom.nextGaussian() * DISORDERED_MAX_ROTATION_RADIANS);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int requestedWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int requestedHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
int childWidth, childHeight;
if (mOrientation == Orientation.Disordered) {
int R1, R2;
if (requestedWidth >= requestedHeight) {
R1 = requestedHeight;
R2 = requestedWidth;
} else {
R1 = requestedWidth;
R2 = requestedHeight;
}
childWidth = (int) ((R1 * Math.cos(DISORDERED_MAX_ROTATION_RADIANS) - R2 * Math.sin(DISORDERED_MAX_ROTATION_RADIANS)) / Math.cos(2 * DISORDERED_MAX_ROTATION_RADIANS));
childHeight = (int) ((R2 * Math.cos(DISORDERED_MAX_ROTATION_RADIANS) - R1 * Math.sin(DISORDERED_MAX_ROTATION_RADIANS)) / Math.cos(2 * DISORDERED_MAX_ROTATION_RADIANS));
} else {
childWidth = requestedWidth;
childHeight = requestedHeight;
}
int childWidthMeasureSpec, childHeightMeasureSpec;
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
assert child != null;
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
for (int i = 0; i < getChildCount(); i++) {
boundsRect.set(0, 0, getWidth(), getHeight());
View view = getChildAt(i);
int w, h;
w = view.getMeasuredWidth();
h = view.getMeasuredHeight();
Gravity.apply(mGravity, w, h, boundsRect, childRect);
view.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
}
}
int holdingCard;
View likeImage, dislikeImage;
#Override
public boolean onTouchEvent(MotionEvent event) {
if (mTopCard == null || animating) {
return false;
}
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
final int pointerIndex;
final float x, y;
final float dx, dy;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
getHitRect(mTopCard,childRect);
pointerIndex = event.getActionIndex();
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (!childRect.contains((int) x, (int) y)) {
return false;
}
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(pointerIndex);
float[] points = new float[]{x - mTopCard.getLeft(), y - mTopCard.getTop()};
mTopCard.getMatrix().invert(mMatrix);
mMatrix.mapPoints(points);
mTopCard.setPivotX(points[0]);
mTopCard.setPivotY(points[1]);
break;
case MotionEvent.ACTION_MOVE:
pointerIndex = event.findPointerIndex(mActivePointerId);
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
dx = x - mLastTouchX;
dy = y - mLastTouchY;
Profile profile = (Profile) getAdapter().getItem(0);
likeImage = mTopCard.findViewById(R.id.like_text_image);
dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
if (mTopCard.getTranslationX() + dx > 30) {
profile.getOnCardDimissedListener().tendToLike();
dislikeImage.setVisibility(View.INVISIBLE);
likeImage.setVisibility(View.VISIBLE);
}
else if (mTopCard.getTranslationX() + dx < 30) {
profile.getOnCardDimissedListener().tendToDislike();
likeImage.setVisibility(View.INVISIBLE);
dislikeImage.setVisibility(View.VISIBLE);
} else {
likeImage.setVisibility(View.INVISIBLE);
dislikeImage.setVisibility(View.INVISIBLE);
}
if (Math.abs(dx) > mTouchSlop || Math.abs(dy) > mTouchSlop) {
mDragging = true;
}
if(!mDragging) {
return true;
}
mTopCard.setTranslationX(mTopCard.getTranslationX() + dx);
mTopCard.setTranslationY(mTopCard.getTranslationY() + dy);
mTopCard.setRotation(40 * mTopCard.getTranslationX() / (getWidth() / 2.f));
mLastTouchX = x;
mLastTouchY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (!mDragging) {
return true;
}
mDragging = false;
mActivePointerId = INVALID_POINTER_ID;
ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTopCard,
PropertyValuesHolder.ofFloat("translationX", 0),
PropertyValuesHolder.ofFloat("translationY", 0),
PropertyValuesHolder.ofFloat("rotation", (float) Math.toDegrees(mRandom.nextGaussian() * DISORDERED_MAX_ROTATION_RADIANS)),
PropertyValuesHolder.ofFloat("pivotX", mTopCard.getWidth() / 2.f),
PropertyValuesHolder.ofFloat("pivotY", mTopCard.getHeight() / 2.f)
).setDuration(250);
animator.setInterpolator(new AccelerateInterpolator());
animator.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
animating = true;
}
#Override
public void onAnimationRepeat(Animator animation) {
animating = true;
}
#Override
public void onAnimationEnd(Animator animation) {
animating = false;
dislikeImage.setVisibility(View.INVISIBLE);
likeImage.setVisibility(View.INVISIBLE);
((Profile) getAdapter().getItem(0)).getOnCardDimissedListener().cancelCard();
}
#Override
public void onAnimationCancel(Animator animation) {
animating = false;
}
});
animator.start();
break;
case MotionEvent.ACTION_POINTER_UP:
pointerIndex = event.getActionIndex();
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = event.getX(newPointerIndex);
mLastTouchY = event.getY(newPointerIndex);
mActivePointerId = event.getPointerId(newPointerIndex);
}
break;
}
return true;
}
private void getHitRect(View v, Rect rect) {
rect.left = (int) (v.getLeft() + v.getTranslationX());
rect.top = (int) (v.getTop() + v.getTranslationY());
rect.right = rect.left + v.getWidth();
rect.bottom = rect.top + v.getHeight();
}
public boolean isAnimating()
{
return animating;
}
public Profile getCurrentCard() {
if(index + 1 > getAdapter().getCount())
return null;
Profile profile = (Profile) getAdapter().getItem(index);
if (index + 1 == getAdapter().getCount())
profile.setLast(true);
return profile;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
try {
Log.e("CARD CONTAINER","MTOPCARD =====================+++++++++ "+mTopCard);
if (mTopCard == null) {
return false;
}
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
final int pointerIndex;
final float x, y;
final float dx, dy;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
getHitRect(mTopCard,childRect);
Profile Profile = (Profile) getAdapter().getItem(0);
if (Profile.getOnClickListener() != null) {
Profile.getOnClickListener().OnClickListener();
}
pointerIndex = event.getActionIndex();
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (!childRect.contains((int) x, (int) y)) {
return false;
}
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(pointerIndex);
break;
case MotionEvent.ACTION_MOVE:
pointerIndex = event.findPointerIndex(mActivePointerId);
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (Math.abs(x - mLastTouchX) > mTouchSlop || Math.abs(y - mLastTouchY) > mTouchSlop) {
float[] points = new float[]{x - mTopCard.getLeft(), y - mTopCard.getTop()};
mTopCard.getMatrix().invert(mMatrix);
mMatrix.mapPoints(points);
mTopCard.setPivotX(points[0]);
mTopCard.setPivotY(points[1]);
return true;
}
}
return false;
} catch (Exception e) {
// TODO Auto-generated catch block
return super.onInterceptTouchEvent(event);
}
}
#Override
public View getSelectedView() {
throw new UnsupportedOperationException();
}
#Override
public void setSelection(int position) {
throw new UnsupportedOperationException();
}
public int getGravity() {
return mGravity;
}
public void setGravity(int gravity) {
mGravity = gravity;
}
public static class LayoutParams extends ViewGroup.LayoutParams {
int viewType;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(int w, int h, int viewType) {
super(w, h);
this.viewType = viewType;
}
}
private class GestureListener extends SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
final View topCard = mTopCard;
float dx = e2.getX() - e1.getX();
if (Math.abs(dx) > mTouchSlop &&
Math.abs(velocityX) > Math.abs(velocityY) &&
Math.abs(velocityX) > mFlingSlop * 3) {
float targetX = topCard.getX();
float targetY = topCard.getY();
long duration = 0;
boundsRect.set(0 - topCard.getWidth() - 100, 0 - topCard.getHeight() - 100, getWidth() + 100, getHeight() + 100);
while (boundsRect.contains((int) targetX, (int) targetY)) {
targetX += velocityX / 10;
targetY += velocityY / 10;
duration += 100;
}
duration = Math.min(400, duration);
cardModel = (Profile) getAdapter().getItem(0);
if (cardModel.getOnCardDimissedListener() != null) {
if ( targetX > 0 ) {
{
if(MyUser.getInstance((Activity)context).getVip().equals("1") || (Float.valueOf((getCurrentCard()).getScore())>MyGenericApp.getInstance((Activity)context).getMinScoreMatch()))
{
mTopCard = getChildAt(getChildCount() - 2);
if (mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
cardModel.getOnCardDimissedListener().onLike();
}
else
{
cardModel.getOnCardDimissedListener().forcedToDislike();
return super.onFling(e1, e2, velocityX, velocityY);
}
}
} else {
mTopCard = getChildAt(getChildCount() - 2);
if (mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
cardModel.getOnCardDimissedListener().onDislike();
}
index++;
}
animating = true;
topCard.animate()
.setDuration(duration)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(targetX)
.y(targetY)
.rotation(Math.copySign(45, velocityX))
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
if(getCurrentCard()!=null)
cardModel.getOnCardDimissedListener().initialiseCard();
animating = false;
}
#Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
return true;
} else
return false;
}
}
public void dislike(){
final View topCard = mTopCard;
View likeImage = mTopCard.findViewById(R.id.like_text_image);
View dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
dislikeImage.setVisibility(View.VISIBLE);
likeImage.setVisibility(View.INVISIBLE);
mTopCard = getChildAt(getChildCount() - 2);
Profile cardModel = (Profile)getAdapter().getItem(0);
if(mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
animating = true;
topCard.animate()
.setDuration(400)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(-GlobalFunctions.getScreenWidth(context))
.y(topCard.getY())
.rotation(-45)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
animating = false;
}
#Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
if(cardModel.getOnCardDimissedListener() != null){
cardModel.getOnCardDimissedListener().onDislike();
}
index++;
if(index < getAdapter().getCount())
((Profile)getAdapter().getItem(0)).getOnCardDimissedListener().initialiseCard();
}
public void like(){
final View topCard = mTopCard;
View likeImage = mTopCard.findViewById(R.id.like_text_image);
View dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
likeImage.setVisibility(View.VISIBLE);
dislikeImage.setVisibility(View.INVISIBLE);
mTopCard = getChildAt(getChildCount() - 2);
Profile cardModel = (Profile)getAdapter().getItem(0);
if(mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
animating = true;
topCard.animate()
.setDuration(400)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(GlobalFunctions.getScreenWidth(context))
.y(topCard.getY())
.rotation(45)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
animating = false;
}
#Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
if(cardModel.getOnCardDimissedListener() != null){
cardModel.getOnCardDimissedListener().onLike();
}
index++;
if(index < getAdapter().getCount())
((Profile)getAdapter().getItem(0)).getOnCardDimissedListener().initialiseCard();
}
}