package com.zulip.android.activities;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.zulip.android.R;
import com.zulip.android.util.ActivityTransitionAnim;
import com.zulip.android.util.DrawCustomView;
import com.zulip.android.util.PhotoHelper;
import static android.graphics.Bitmap.createBitmap;
public class PhotoEditActivity extends AppCompatActivity {
private String mPhotoPath;
private ImageView mImageView;
private DrawCustomView mDrawCustomView;
private SimpleTarget mGlideTarget;
private int[] mImageDimensions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_edit);
// set a border and color for black marker color
ImageView black_marker = (ImageView) findViewById(R.id.black_marker);
GradientDrawable blackCircle = (GradientDrawable) black_marker.getDrawable();
blackCircle.setColor(ContextCompat.getColor(this, R.color.black_marker_tool));
blackCircle.setStroke(3, Color.GRAY);
// change background of marker tool to default color red on activity start up
int colorId = R.color.red_marker_tool;
ImageView markerIcon = (ImageView) findViewById(R.id.marker_btn);
GradientDrawable markerBackground = (GradientDrawable) markerIcon.getBackground();
markerBackground.setColor(ContextCompat.getColor(this, colorId));
markerBackground.setStroke(0, Color.GRAY);
// run activity in full screen mode
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// get file path of image from PhotoSendActivity
final Intent intent = getIntent();
mPhotoPath = intent.getStringExtra(Intent.EXTRA_TEXT);
mImageView = (ImageView) findViewById(R.id.photoImageView);
mDrawCustomView = (DrawCustomView) findViewById(R.id.draw_custom_view);
// glide target called when image is loaded
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
mGlideTarget = new SimpleTarget<Bitmap>(width, height) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// set bitmap on imageView
mImageView.setImageBitmap(bitmap);
// bound the canvas for drawing to the actual dimensions of imageView
mImageDimensions = PhotoHelper.getBitmapPositionInsideImageView(mImageView);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
mImageDimensions[2],
mImageDimensions[3]
);
params.setMargins(mImageDimensions[0], mImageDimensions[1], 0, 0);
mDrawCustomView.setLayoutParams(params);
}
};
// use glide to take care of high performance bitmap decoding
Glide
.with(this)
.load(mPhotoPath)
.asBitmap()
.into(mGlideTarget);
// set up undo button
ImageView undoBtn = (ImageView) findViewById(R.id.undo_btn);
undoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDrawCustomView.onClickUndo();
}
});
// go back when back button is pressed
ImageView backBtn = (ImageView) findViewById(R.id.back_btn);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PhotoEditActivity.super.onBackPressed();
}
});
// set up crop button
// intent to go back to PhotoSendActivity
final Intent cropIntent = new Intent(this, PhotoSendActivity.class);
cropIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
TextView cropBtn = (TextView) findViewById(R.id.crop_btn);
cropBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// pass edited photo file path to PhotoSendActivity
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.frame_layout_picture);
frameLayout.setVisibility(View.INVISIBLE);
// take screenshot of cropped image
if (frameLayout.getWidth() > 0 && frameLayout.getHeight() > 0) {
Bitmap bitmap = screenShot(frameLayout);
mPhotoPath = PhotoHelper.saveBitmapAsFile(mPhotoPath, bitmap);
cropIntent.putExtra(PhotoEditActivity.class.getSimpleName(), true);
cropIntent.putExtra(Intent.EXTRA_TEXT, mPhotoPath);
startActivity(cropIntent);
// activity transition animation
ActivityTransitionAnim.transition(PhotoEditActivity.this);
} else {
// do nothing
// wait for layout to be constructed
}
}
});
// intent to go back to ZulipActivity and upload photo
// when send button is clicked
ImageView sendPhoto = (ImageView) findViewById(R.id.send_photo);
final Intent sendIntent = new Intent(this, ZulipActivity.class);
sendIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
sendPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// pass edited photo file path to ZulipActivity
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.frame_layout_picture);
frameLayout.setVisibility(View.INVISIBLE);
// take screenshot of cropped image
if (frameLayout.getWidth() > 0 && frameLayout.getHeight() > 0) {
Bitmap bitmap = screenShot(frameLayout);
mPhotoPath = PhotoHelper.saveBitmapAsFile(mPhotoPath, bitmap);
sendIntent.putExtra(Intent.EXTRA_TEXT, mPhotoPath);
startActivity(sendIntent);
// activity transition animation
ActivityTransitionAnim.transition(PhotoEditActivity.this);
} else {
// do nothing
// wait for layout to be constructed
}
}
});
}
/**
* This function is called when any of the marker colors are chosen.
* Its sets the color for marker tool and changes its the background.
*
* @param view color ImageView
*/
public void handleMarkerColorChange(View view) {
int colorId = R.color.red_marker_tool;
switch (view.getId()) {
case R.id.red_marker:
colorId = R.color.red_marker_tool;
break;
case R.id.yellow_marker:
colorId = R.color.yellow_marker_tool;
break;
case R.id.green_marker:
colorId = R.color.green_marker_tool;
break;
case R.id.white_marker:
colorId = R.color.white_marker_tool;
break;
case R.id.blue_marker:
colorId = R.color.blue_marker_tool;
break;
case R.id.black_marker:
colorId = R.color.black_marker_tool;
break;
default:
Log.e("Marker Tool", "Invalid color");
break;
}
// change marker tool color
mDrawCustomView.setBrushColor(ContextCompat.getColor(this, colorId));
// change background of marker tool
ImageView markerIcon = (ImageView) findViewById(R.id.marker_btn);
GradientDrawable markerBackground = (GradientDrawable) markerIcon.getBackground();
markerBackground.setColor(ContextCompat.getColor(this, colorId));
// if black color is selected, add a border to the background of marker tool
if (colorId == R.color.black_marker_tool) {
markerBackground.setStroke(3, Color.GRAY);
} else {
markerBackground.setStroke(0, Color.GRAY);
}
}
/**
* Function that takes a screenshot of the view passed and returns a bitmap for it.
*
* @param view {@link View}
* @return screenshot of the view passed
*/
public Bitmap screenShot(View view) {
// Define a bitmap with the same size as the view
Bitmap returnedBitmap = createBitmap(view.getWidth(), view.getHeight(),
Bitmap.Config.RGB_565);
// Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
// Get the view's background
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
// has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
// does not have background drawable, then draw black background on
// the canvas
canvas.drawColor(Color.BLACK);
// draw the view on the canvas
view.draw(canvas);
// obtained only the visible region of edited image
Bitmap trimmedBitmap = null;
if (mImageDimensions != null) {
trimmedBitmap = Bitmap.createBitmap(returnedBitmap,
mImageDimensions[0], mImageDimensions[1],
mImageDimensions[2], mImageDimensions[3]);
}
return trimmedBitmap;
}
}