Erase paint drawn on canvas - java

I am trying to develop a finger paint type app using a demo, everything is fine except the erasing function.
My MainActivity is,
public class MainActivity extends Activity implements OnClickListener {
//custom drawing view
private DrawingView drawView;
//buttons
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
//sizes
private float smallBrush, mediumBrush, largeBrush;
//to save image
Bitmap saveImageBM;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currPaint = (ImageButton)paintLayout.getChildAt(0);
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
//sizes from dimensions
smallBrush = getResources().getInteger(R.integer.small_size);
mediumBrush = getResources().getInteger(R.integer.medium_size);
largeBrush = getResources().getInteger(R.integer.large_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener(this);
//set initial size
drawView.setBrushSize(smallBrush);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener(this);
//new button
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener(this);
//save button
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//user clicked paint
public void paintClicked(View view){
//use chosen color
//set erase false
drawView.setErase(false);
drawView.setBrushSize(drawView.getLastBrushSize());
if(view!=currPaint){
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update ui
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
//called when draw_btn clicked
#Override
public void onClick(View view){
if(view.getId()==R.id.draw_btn){
//draw button clicked
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Brush size:");
brushDialog.setContentView(R.layout.brush_chooser);
//listen for clicks on size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
brushDialog.dismiss();
}
});
//show and wait for user interaction
brushDialog.show();
}
else if(view.getId()==R.id.erase_btn){
//switch to erase - choose size
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Eraser size:");
brushDialog.setContentView(R.layout.brush_chooser);
//size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(smallBrush);
/*drawView.clearPoints();*/
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(largeBrush);
brushDialog.dismiss();
}
});
brushDialog.show();
}
else if(view.getId()==R.id.new_btn){
//new button
AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
newDialog.setTitle("New drawing");
newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
drawView.startNew();
dialog.dismiss();
}
});
newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
newDialog.show();
}
else if(view.getId()==R.id.save_btn){
//save drawing
AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
saveDialog.setTitle("Save drawing");
saveDialog.setMessage("Save drawing to device Gallery?");
saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
//save drawing
drawView.setDrawingCacheEnabled(true);
//attempt to save
saveImageBM = drawView.getDrawingCache();
Log.i("image", " "+saveImageBM);
if (saveImageBM!=null) {
saveImage(saveImageBM);
}else{
Toast.makeText(getApplicationContext(), "Image is not saved", Toast.LENGTH_SHORT).show();
}
/*String imgSaved = MediaStore.Images.Media.insertImage(
getContentResolver(), drawView.getDrawingCache(),
UUID.randomUUID().toString()+".png", "drawing");*/
//feedback
/*if(imgSaved!=null){
Toast.makeText(getApplicationContext(), "Drawing saved to Gallery!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Oops! Image could not be saved.", Toast.LENGTH_SHORT).show();
}*/
drawView.destroyDrawingCache();
}
});
saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
saveDialog.show();
}
}
private void saveImage(Bitmap bitmap)
{
// save to folder in sd card
try
{
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "winoria");
if(!imagesFolder.exists())
imagesFolder.mkdirs();
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
if(megAvailable>20)
{
String fileName=""+System.currentTimeMillis()+".jpg";
File output = new File(imagesFolder, fileName);
OutputStream fOut = new FileOutputStream(output);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
/*Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(Environment.getExternalStorageDirectory(), "winoria/"+fileName);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent); */
fOut.flush();
fOut.close();
Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getApplicationContext(), "No enough space available", Toast.LENGTH_SHORT).show();
}
catch (FileNotFoundException e) {
//e.printStackTrace();
Toast.makeText(getApplicationContext(),"SlideShowFragement:"+e.toString(),Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"SlideShowFragement:"+e.toString(),Toast.LENGTH_LONG).show();
//e.printStackTrace();
}
}
}
And my View is,
public class DrawingView extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//brush sizes
private float brushSize, lastBrushSize;
//erase flag
private boolean erase=false;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
brushSize = getResources().getInteger(R.integer.small_size);
lastBrushSize = brushSize;
drawPath = new Path();
drawPaint = new Paint();
//set initial color
drawPaint.setColor(paintColor);
//set initial path properties
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);//we have two options Fill and STROKE
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//will be called when the custom View is assigned a size:
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw the view - will be called after touch event
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//register user touches as drawing action
#Override
public boolean onTouchEvent(MotionEvent event) {
//retrieve the X and Y positions of the user touch:
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://A pressed gesture has started, the motion contains the initial starting location.
drawPath.moveTo(touchX, touchY);//Set the beginning of the next contour to the point (x,y)
//extra code for erase
//mPaint.setStrokeWidth(25);
/*if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawCanvas.drawCircle(touchX, touchY, 10, drawPaint);
}
invalidate();*/
break;
case MotionEvent.ACTION_MOVE://A change has happened during a press gesture (between ACTION_DOWN and ACTION_UP).
drawPath.lineTo(touchX, touchY);//Add a line from the last point to the specified point (x,y)
//extra code for erase
/*if(erase){
drawCanvas.drawCircle(touchX, touchY, 20, drawPaint);
}
else{
drawPath.lineTo(touchX, touchY);
}invalidate();*/
break;
case MotionEvent.ACTION_UP://A pressed gesture has finished, the motion contains the final release location as well as any intermediate points since the last down or move event
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);//Draw the specified path using the specified paint.
//drawPath.rewind();
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//update color
public void setColor(String newColor){
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
//set brush size
public void setBrushSize(float newSize){
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
//get and set last brush size
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
//set erase true or false
public void setErase(boolean isErase){
erase=isErase;
if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
}
else{
drawPaint.setXfermode(null);
}
}
//start new drawing
public void startNew(){
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
}
Problem part is the setErase function, when i erase the paint it shows black shadow and I want to remove that so please suggest me how can I fix that.

Related

Taking a score from one activity to another in Android app

I've been trying to work this out but to no avail.
I have a score that is obtained in the GameView class using the int hitCount inside the onTouchEvent method. This is being calculated fine. What I need to do is pass the total score to MainMenu class where it says 'Total Number of Hits'.
I have this 'finish' method in the GameActivity class:
public void finish(){
Intent returnIntent=new Intent();
returnIntent.putExtra("GAME_SCORE",gameView.getHitCount());
setResult(RESULT_OK,returnIntent);
super.finish();
}
GameView class:
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
/* Member (state) fields */
private GameLoopThread gameLoopThread;
private Paint paint; //Reference a paint object
/**
* The drawable to use as the background of the animation canvas
*/
private Bitmap mBackgroundImage;
// For creating the game Sprite
private Sprite sprite;
// For recording the number of hits
private int hitCount;
// To track if a game is over
private boolean gameOver;
// To play sound
private SoundPlayer sound;
//int backButtonCount = 0;
public GameView(Context context) {
super(context);
// Focus must be on GameView so that events can be handled.
this.setFocusable(true);
// For intercepting events on the surface.
this.getHolder().addCallback(this);
// Background image added
mBackgroundImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.half_moon);
//sound = new SoundPlayer(this);
}
/* Called immediately after the surface created */
public void surfaceCreated(SurfaceHolder holder) {
// We can now safely setup the game start the game loop.
ResetGame();//Set up a new game up - could be called by a 'play again option'
mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, getWidth(), getHeight(), true);
gameLoopThread = new GameLoopThread(this.getHolder(), this);
gameLoopThread.running = true;
gameLoopThread.start();
}
// For the countdown timer
private long startTime; // Timer to count down from
private final long interval = 1 * 1000; // 1 sec interval
private CountDownTimer countDownTimer; // Reference to the class
private boolean timerRunning = false;
private String displayTime; // To display the time on the screen
//To initialise/reset game
private void ResetGame() {
/* Set paint details */
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(20);
sprite = new Sprite(this);
hitCount = 0;
// Set timer
startTime = 10; // Start at 10s to count down
// Create new object - convert startTime to milliseconds
countDownTimer = new MyCountDownTimer(startTime * 1000, interval);
countDownTimer.start(); // Start the time running
timerRunning = true;
gameOver = false;
}
// Countdown Timer - private class
private class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
public void onFinish() {
//displayTime = "Time is up!";
timerRunning = false;
countDownTimer.cancel();
gameOver = true;
}
public void onTick(long millisUntilFinished) {
displayTime = " " + millisUntilFinished / 1000;
}
}
//This class updates and manages the assets prior to drawing - called from the Thread
public void update() {
sprite.update();
}
/**
* To draw the game to the screen
* This is called from Thread, so synchronisation can be done
*/
public void doDraw(Canvas canvas) {
//Draw all the objects on the canvas
canvas.drawBitmap(mBackgroundImage, 0, 0, null);
if (!gameOver) {
sprite.draw(canvas);
canvas.drawText("Time Remaining: " + displayTime, 35, 50, paint);
canvas.drawText("Number of hits: " + hitCount, 250, 50, paint);
} else {
canvas.drawText("Game Over!", 185, 100, paint);
canvas.drawText("To go back to the main menu, press the 'back' key", 15, 150, paint);
}
}
//To be used if we need to find where screen was touched
public boolean onTouchEvent(MotionEvent event) {
if (sprite.wasItTouched(event.getX(), event.getY())) {
// This just renews the sprite for now
sprite = new Sprite(this);
//sound.playZapSound();
hitCount++;
}
return true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
gameLoopThread.running = false;
// Shut down the game loop thread cleanly.
boolean retry = true;
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
public void getHitCount() {
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
}
MainMenu class:
public class MainMenu extends Activity {
private static final int SCORE_REQUEST_CODE = 1;// The request code for the intent
TextView tvScore;
String score;
Intent gameIntent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_start);
}
public void startGame(View v) {
gameIntent = new Intent(this, GameActivity.class);
startActivityForResult(gameIntent, SCORE_REQUEST_CODE);
}
/* Create Options Menu */
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
// Respond to item selected on OPTIONS MENU
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
//put data in Intent
case R.id.easy:
Toast.makeText(this, "Easy chosen", Toast.LENGTH_SHORT).show();
return true;
case R.id.medium:
Toast.makeText(this, "Medium chosen", Toast.LENGTH_SHORT).show();
return true;
case R.id.hard:
Toast.makeText(this, "Hard chosen", Toast.LENGTH_SHORT).show();
return true;
case R.id.other:
Toast.makeText(this, "Other chosen", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent retIntent) {
// Check which request we're responding to
if (requestCode == SCORE_REQUEST_CODE) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
if (retIntent.hasExtra("GAME_SCORE")) {
int scoreFromGame = retIntent.getExtras().getInt("GAME_SCORE");
tvScore.setText(Integer.toString(scoreFromGame));
}
}
}
}
}
Any advice greatly appreciated.
Thanks
UPDATE:
I have added 'return hitCount;' to the 'getHitCount' method in the 'GameView' class and this now just crashes the app when I hit the back key. One the 'MainMenu' class, I have taken out the last line in the 'onActivityResult' method (tvScore.setText(Integer.toString(scoreFromGame)); and it no longer crashes but obviously doesn't pass the score across. I don't know where to go from here.
While fetching data from intent you have to use -
int scoreFromGame = retIntent.getIntExtra("GAME_SCORE", -1);
// -1 is a default value, use accordingly.
Instead of trying to get value from extras.
retIntent.getExtras().getInt("GAME_SCORE");
Use extras only when you put some value inside bundle.

Shared Preferences ImageView

I'm working in android studios and I have this app that displays an imageView and has seekbars that allow you to edit the RGB values of the photo, but when I rotate from portrait to landscape (or vice versa) the imageView doesnt save and goes back to the original imageView and not the one that I selected. The Seekbars keep their values though. Any ideas on how I can used shared preferences to save the image? Thanks
public class MainActivity extends AppCompatActivity {
////////////////////////////////////////////////////////////////////////////
TextView textTitle;
ImageView image;
SeekBar barR, barG, barB, barAlpha;
int ColorValues;
private static final int SELECT_PHOTO = 100;
private static final int CAMERA_PIC_REQUEST = 101;
private static final String PREFS_NAME = "PrefsFile";
private static final String COLOR_VALUES = "ColorVals";
private static final String PICTURE = "Picture";
///////////////////////////////////////////////////////////////////////////
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textTitle = (TextView)findViewById(R.id.title);
image = (ImageView)findViewById(R.id.image);
barR = (SeekBar)findViewById(R.id.red);
barG = (SeekBar)findViewById(R.id.green);
barB = (SeekBar)findViewById(R.id.blue);
barAlpha = (SeekBar)findViewById(R.id.alpha);
barR.setOnSeekBarChangeListener(myOnSeekBarChangeListener);
barG.setOnSeekBarChangeListener(myOnSeekBarChangeListener);
barB.setOnSeekBarChangeListener(myOnSeekBarChangeListener);
barAlpha.setOnSeekBarChangeListener(myOnSeekBarChangeListener);
//default color
ColorValues = barAlpha.getProgress() * 0x1000000
+ barR.getProgress() * 0x10000
+ barG.getProgress() * 0x100
+ barB.getProgress();
image.setColorFilter(ColorValues, Mode.MULTIPLY);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
ColorValues = settings.getInt(COLOR_VALUES, ColorValues);
}
//menu/////////////////
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.savePicture:
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
MediaStore.Images.Media.insertImage
(getContentResolver(), bitmap, "yourTitle", "yourDescription");
}
return true;
}
//on click function////////////////
public void selectPicture(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
public void takePicture(View view){
try{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
} catch(Exception e){
e.printStackTrace();
}
}
//activity///////////////
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
image.setImageURI(selectedImage);// To display selected image in image view
break;
}
case CAMERA_PIC_REQUEST:
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
thumbnail = Bitmap.createScaledBitmap(thumbnail, 700, 500, true);
ImageView imageView = (ImageView) findViewById(R.id.image);
image.setImageBitmap(thumbnail);
} catch (Exception ee) {
ee.printStackTrace();
}
break;
}
}
//warning before exit
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing Activity")
.setMessage("Are you sure you want to close\nthis activity? \n\nProgress will NOT be saved ")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("No", null);
AlertDialog dialog = builder.show();
TextView messageText = (TextView)dialog.findViewById(android.R.id.message);
messageText.setGravity(Gravity.CENTER);
dialog.show();
}
//edit picture
OnSeekBarChangeListener myOnSeekBarChangeListener = new OnSeekBarChangeListener(){
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
//Colorize ImageView
int newColor = barAlpha.getProgress() * 0x1000000
+ barR.getProgress() * 0x10000
+ barG.getProgress() * 0x100
+ barB.getProgress();
image.setColorFilter(newColor, Mode.MULTIPLY);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
ColorValues = newColor;
editor.putInt(COLOR_VALUES, ColorValues);
// Commit the edits
editor.commit();
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {}
};
#Override
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
icicle.putInt(COLOR_VALUES, ColorValues);
}
this is what it would look like if I saved the colorvalues(which are somehow already being saved without this code)
if (savedInstanceState != null) {
colorvalues = savedInstanceState.getInt("COLOR_VALUES");
image = savedInstanceState.get??????????????????????
}
image is not an Int so what values should be put there?
also to get the exact RGB values like RBar = savedInstanceState.getInt doesnt works becuase Rbar is a seekbar not an int???

Save image taken to a specific directory with specific name

I am having trouble saving the image taken to a specific directory with specific name. I have no idea how to do it. Below is my code.
CameraCaptureImage.java
public class CaptureCameraImage extends Activity {
public static int cameraID = 0;
public static boolean isBlack = true;
public static ImageView image;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activitycapturecameraimage);
image = (ImageView) findViewById(R.id.imgView);
}
public void onBackClick(View v){
cameraID = 0;
Intent i = new Intent(CaptureCameraImage.this,CameraView.class);
startActivityForResult(i, 999);
}
}
CameraView.java
public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener{
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
#SuppressWarnings("deprecation")
public void onCreate(Bundle icicle){
super.onCreate(icicle);
Log.e(TAG, "onCreate");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.cameraview);
ImageView img = (ImageView) findViewById(R.id.blankImage);
if(CaptureCameraImage.isBlack)
img.setBackgroundResource(android.R.color.black);
else
img.setBackgroundResource(android.R.color.white);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if (data != null){
//Intent mIntent = new Intent();
//mIntent.putExtra("image",imageData);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
try{
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts);
bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = 300;
int newHeight = 300;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(90);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
width, height, matrix, true);
CaptureCameraImage.image.setImageBitmap(resizedBitmap);
}catch(Exception e){
e.printStackTrace();
}
//StoreByteImage(mContext, imageData, 50,"ImageName");
//setResult(FOTO_MODE, mIntent);
setResult(585);
finish();
}
}
};
protected void onResume(){
Log.e(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
}
protected void onStop(){
Log.e(TAG, "onStop");
super.onStop();
}
#TargetApi(9)
public void surfaceCreated(SurfaceHolder holder){
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open(CaptureCameraImage.cameraID);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning){
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(300, 300);
if(CaptureCameraImage.cameraID == 0){
String stringFlashMode = p.getFlashMode();
if (stringFlashMode.equals("torch"))
p.setFlashMode("on"); // Light is set off, flash is set to normal 'on' mode
else
p.setFlashMode("torch");
}
mCamera.setParameters(p);
try{
mCamera.setPreviewDisplay(holder);
}catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
//mCamera.stopPreview();
//mPreviewRunning = false;
//mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
}
To capture an image and save it in a specific folder, you have to :
Request for permission on runtime (API 23)
Request image capture
Create the folder
First of all, if you target API 23, you have to follow the new permission system which asks the user to grant it only when used for the first time. In your case, you need to have WRITE_EXTERNAL_STORAGE granted.
boolean hasPermission = (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
Then, you need to create an implicit intent to capture a photo. The camera app could appear in the app chooser or be selected automatically depending on user settings and installed apps.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); // final int = 1
Finally, you need to create the folder and indicate the extra output so Android will know where to save the picture.
//Intent i = new intent...
long timestamp = System.currentTimeMillis();
File file = new File("");
file = new File(Environment.getExternalStorageDirectory()
+ File.separator
+ "DCIM"
+ File.separator
+ address
+ File.separator
, "IMG_" + String.valueOf(timestamp) + ".jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
//startActivityForResult...
There are a lot of storage possibilities. You can take a look here :
https://developer.android.com/training/basics/data-storage/files.html
I have done nothing special in onActivityResult callback method. I only show a toast to confirm the user that the picture is saved successfully. All the code above is in the onClickListener of an imageView in my case.

Togglebutton in combination with Intent to display Image in Android

I am using togglebutton to switch between images obtained using Intent (selected from sdcard). However i have an error after i select image. Basically my idea is to browse an image and display on (originalimage) Imageview based on the state of togglebutton. Moreover when i change the state of togglebutton i should see different images.
public class LoadImage extends AppCompatActivity {
public static final int REQUEST_CODE = 10;
ToggleButton togglebtn;
Bitmap imgb;
Button browseimagebtn;
Bitmap operation;
ImageView originalimage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_load);
originalimage = (ImageView) findViewById(R.id.originalimage);
browseimagebtn = (Button) findViewById(R.id.browseimagebtn);
//browse image button clicked
browseimagebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent rawIntent = new Intent(Intent.ACTION_PICK);
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
String pictureDirectoryPath = pictureDirectory.getPath();
Uri data=Uri.parse(pictureDirectoryPath);
rawIntent.setDataAndType(data, "image/*");
startActivityForResult(rawIntent, REQUEST_CODE);
}
});
//browse image button long pressed
browseimagebtn.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(getApplicationContext(), "Loads image from Picture Gallery", Toast.LENGTH_SHORT).show();
return true;
}
});
//toggle switch to decide which image to be displayed on screen
togglebtn = (ToggleButton) findViewById(R.id.togglebtn);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK){
if(requestCode==REQUEST_CODE){
final float red = (float) 0.299;
final float green = (float) 0.587;
final float blue = (float) 0.114;
final Uri imagef = data.getData();
InputStream streamI;
try {
streamI = getContentResolver().openInputStream(imagef);
//Create bitmap from selected image
Bitmap imgb = BitmapFactory.decodeStream(streamI);
//Define rows and columns of selected image
int rows = imgb.getHeight();int cols = imgb.getWidth();
operation = Bitmap.createBitmap(cols, rows, imgb.getConfig());
//Convert original image to Gray Image
for (int i=0;i<cols;i++){
for(int j=0;j<rows;j++){
int p = imgb.getPixel(i,j);
int r = Color.red(p);
int g = Color.green(p);
int b = Color.blue(p);
r = (int) (red*r);
g = (int) (green*g);
b = (int) (blue*b);
int gray = (int) (r*0.299+g*0.587+b*0.114);
operation.setPixel(i, j, Color.argb(Color.alpha(p), gray, gray, gray));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();}
}
togglebtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Toast.makeText(getApplicationContext(), "if is checked", Toast.LENGTH_SHORT).show();
originalimage.setImageBitmap(operation);
} else {
Toast.makeText(getApplicationContext(), "else is checked", Toast.LENGTH_SHORT).show();
originalimage.setImageBitmap(imgb);
}
}
});
}
}
}
Not sure if this fixes everything but:
Bitmap imgb -> will always be null.
Fix:
In your onActivityResult:
try {
streamI = getContentResolver().openInputStream(imagef);
//Create bitmap from selected image
imgb = BitmapFactory.decodeStream(streamI);
.....
}
Included Android permission.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

can i erase the part or full of a image which is loaded from the SD card to the canvas or DrawView

iam successfully getting the image from the SD card to the canvas but i want to erase some part of the loaded image.... suggest me suitable code this is my main activity and i can draw on canvas save the content and i can erase the drawn content but i have to erase the loaded image please suggest me
//custom drawing view
private DrawingView drawView;
//buttons
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn,loadBtn;
//sizes
private float Brush;
Bitmap bitmap;
int mWidth;
int mHeight;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWidth=mHeight=0;
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currPaint = (ImageButton)paintLayout.getChildAt(0);
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
//sizes from dimensions
Brush = getResources().getInteger(R.integer.small_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener(this);
//set initial size
drawView.setBrushSize(Brush);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener(this);
//new button
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener(this);
//save button
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener(this);
//load button
loadBtn = (ImageButton)findViewById(R.id.load_btn);
loadBtn.setOnClickListener(this);
}
private Bitmap getBitmapFromUri(Uri data){
Bitmap bitmap = null;
// Starting fetch image from file
InputStream is=null;
try {
is = getContentResolver().openInputStream(data);
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// BitmapFactory.decodeFile(path, options);
BitmapFactory.decodeStream(is, null, options);
// Calculate inSampleSize
// options.inSampleSize = calculateInSampleSize(options, mWidth, mHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
is = getContentResolver().openInputStream(data);
bitmap = BitmapFactory.decodeStream(is,null,options);
if(bitmap==null){
Toast.makeText(getBaseContext(), "Image is not Loaded",Toast.LENGTH_SHORT).show();
return null;
}
is.close();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(NullPointerException e){
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == 10 && resultCode == RESULT_OK && null != intent) {
Uri data = intent.getData();
Bitmap bitmap = getBitmapFromUri(data);
if(bitmap!=null){
drawView.addBitmap(bitmap);
}
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
mWidth = drawView.getWidth();
mHeight = drawView.getHeight();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("width", mWidth);
outState.putInt("height", mHeight);
if(drawView.getBitmap()!=null){
outState.putParcelable("bitmap", drawView.getBitmap());
}
super.onSaveInstanceState(outState);
}
public void paintClicked(View view){
//use chosen color
//set erase false
drawView.setErase(false);
drawView.setPaintAlpha(100);
drawView.setBrushSize(Brush);
if(view!=currPaint){
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update ui
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
#Override
public void onClick(View view){
if(view.getId()==R.id.draw_btn){
drawView.setErase(false);
drawView.setBrushSize(Brush);
drawView.setLastBrushSize(Brush);
}
else if(view.getId()==R.id.erase_btn){
//switch to erase - choose size
final Dialog brushDialog = new Dialog(this);
drawView.setErase(true);
drawView.setBrushSize(getResources().getInteger(R.integer.medium_size));
brushDialog.dismiss();
}
if(view.getId()==R.id.new_btn){
//new button
AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
newDialog.setTitle("Clear Drawing");
newDialog.setMessage("Are You Sure To Clear (you will lose the current drawing)?");
newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
#SuppressLint("NewApi") public void onClick(DialogInterface dialog, int which){
drawView.deleteBitmap();
drawView.startNew();
dialog.dismiss();
}
});
newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
newDialog.show();
}
else if(view.getId()==R.id.save_btn){
//save drawing
AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
saveDialog.setTitle("Save drawing");
saveDialog.setMessage("Save drawing to device Gallery?");
saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
//save drawing
drawView.setDrawingCacheEnabled(true);
//attempt to save
String imgSaved = MediaStore.Images.Media.insertImage(
getContentResolver(), drawView.getDrawingCache(),
UUID.randomUUID().toString()+".png", "drawing");
//feedback
if(imgSaved!=null){
Toast savedToast = Toast.makeText(getApplicationContext(),
"Drawing saved to Gallery!", Toast.LENGTH_SHORT);
savedToast.show();
}
else{
Toast unsavedToast = Toast.makeText(getApplicationContext(),
"Oops! Image could not be saved.", Toast.LENGTH_SHORT);
unsavedToast.show();
}
drawView.destroyDrawingCache();
}
});
saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
saveDialog.show();
}
else if (view.getId()==R.id.load_btn){
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
Intent customChooserIntent = Intent.createChooser(i, "Pick an image");
startActivityForResult(customChooserIntent, 10);
}
}
}

Categories

Resources