How to save an Image after drawing on it - android

I am using this tutorial for creating a drawing app in android.
What I am trying to do is get an image from gallery and then after painting on it, trying to save it.
After drawing, when I try to save the image it only saves the drawing with black background. The image taken from the gallery is not visible in saved image.
My Code:
XML Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFCCCCCC"
android:orientation="vertical"
tools:context=".ImageActivity" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/my_save_btn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:contentDescription="#string/save"
android:src="#drawable/save" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:id="#+id/my_view_drawing_pad1"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="3dp"
android:layout_weight="1" >
<LinearLayout
android:id="#+id/my_view_drawing_pad"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
ImageActivity class:
public class ImageActivity extends Activity implements OnClickListener
{
private DrawingView drawView;
private ImageButton ibsaveBtn;
LinearLayout llDrawingPad;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
drawView = new DrawingView(this);
llDrawingPad = (LinearLayout) findViewById(R.id.my_view_drawing_pad);
ibsaveBtn = (ImageButton)findViewById(R.id.my_save_btn);
ibsaveBtn.setOnClickListener(this);
// code to get image from gallery ...
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
// getting the image
File file = new File(s);
if (file.exists()) {
fp = file.getAbsolutePath();
d = Drawable.createFromPath(file.getAbsolutePath());
drawView = new DrawingView(this);
llDrawingPad = (LinearLayout) findViewById(R.id.my_view_drawing_pad);
llDrawingPad.addView(drawView);
llDrawingPad.setBackgroundDrawable(d);
}
} // end onActivityResult
#Override
public void onClick(View view)
{
drawView.setDrawingCacheEnabled(true);
drawView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
String imgSaved = MediaStore.Images.Media.insertImage(
getContentResolver(), drawView.getDrawingCache(), UUID.randomUUID()
.toString() + ".png", "drawing");
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();
} // end onClick
What am I missing here??

try eliminate this line
drawView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

Try doing this in your onClick:
drawView = new DrawingView(this);
drawView.setDrawingCacheEnabled(true);
Bitmap bitmap = drawView.getDrawingCache();
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File(path+"image.png");
FileOutputStream ostream;
try {
file.createNewFile();
ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.flush();
ostream.close();
Toast.makeText(getApplicationContext(), "image saved", 5000).show();
}
catch (Exception e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "error", 5000).show();
}

Related

Listview Items not getting displayed when converting XML Layout to bitmap image

I've been trying to convert an XML Layout to bitmap image. When i click on the convert button, image is being generated. But my ListView items are not getting displayed. How can i do that?
Following is my code
mView = findViewById(R.id.f_view);
mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(this);
mView.setDrawingCacheEnabled(true);
mView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
mView.buildDrawingCache(true);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
Bitmap b = Bitmap.createBitmap(mView.getDrawingCache());
mView.setDrawingCacheEnabled(false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Expense Calculator" + File.separator + "Expense.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
Toast.makeText(null, getApplicationContext()+ "Image Generated", Toast.LENGTH_SHORT).show();
fo.close();
} catch (Exception e) {
}
//finish();
}
}
and my xml code is as follows
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<include android:id="#+id/f_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
layout="#layout/view_expense"
android:layout_above="#id/button1"/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="54dp"
android:background="#drawable/cimage" />
</RelativeLayout>
What should i do to get my listview items displayed? Can Someone help me please?
Thanks
Enable drawing cache only when you want to get Bitmap from on-click.
mView.buildDrawingCache(true);
Remove above line form onCreate() methdod.
You Need to disable DrawingCache immediately after generating Bitmap from View
like below code:
mView.destroyDrawingCache();
Try Below onClick Code:
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
mView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mView.getDrawingCache());
mView.setDrawingCacheEnabled(false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Expense Calculator" + File.separator + "Expense.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
Toast.makeText(null, getApplicationContext()+ "Image Generated", Toast.LENGTH_SHORT).show();
fo.close();
} catch (Exception e) {
}
//finish();
}
Use Below method to get bitmap from view you can pass view in this method :
public Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(canvas);
return returnedBitmap;
}

after taking screenshot the layout are streached

I created screen shot activity in programatically in android.using scroll view the after taking screen shot the layout are stretched. I will give the images for before taking after taking screen shot.this will help you to understand my problem.i don't know how to tell?
before taking screen shot the layout ,
after taking screen shot the layout
you know the difference of two images.the activity after taking screen shot it extended i don't know why it happen? how to solve this?
My code :
public class MainActivity extends AppCompatActivity {
File cacheDir;
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button print = (Button) findViewById(R.id.btn_print);
print.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takeScreenShot();
}
});
}
private void takeScreenShot() {
View u = findViewById(R.id.activity_main);
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
u.measure(spec, spec);
u.layout(0, 0, u.getMeasuredWidth(), u.getMeasuredHeight());
Bitmap b = getBitmapFromView(u,u.getMeasuredHeight(),u.getMeasuredWidth());
final String root = Environment.getExternalStorageDirectory().toString();
File myPath = new File(root + "/saved_img");
myPath.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+n+".jpg";
File file = new File(myPath, fname);
FileOutputStream fos = null;
if(file.exists()) file.delete();
try{
fos = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch(FileNotFoundException e){
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
Toast.makeText(this,"screen captured",Toast.LENGTH_SHORT).show();
}
public Bitmap getBitmapFromView(View u, int totalHeight, int totalWidth){
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = u.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
u.draw(canvas);
return returnedBitmap;
}
}
xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.own.scrollviewimg.MainActivity"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="print"
android:id="#+id/btn_print"
/>
<ScrollView
android:id="#+id/horizontalscroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_width="500dp"
android:layout_height="200dp"
android:src="#mipmap/ic_launcher"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/testdata"
android:textSize="25sp"
android:textStyle="bold"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
</RelativeLayout>
try this code
private void takeScreenShot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
In your takeScreenShot() block, why are you using View.MeasureSpec
You can use view.getMeasuredHeight() and view.getMeasuredWidth() to the the height and width from the root view itself and also try to get the view from already inflated root by
View view = getWindow().getDecorView().getRootView();
So just comment out
/* int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
u.measure(spec, spec);
u.layout(0, 0, u.getMeasuredWidth(), u.getMeasuredHeight()); */
and the rest is fine
Note: the width of your ImageView may be more than the current screen size
finally i found the answer.it's simple.i just recall the layout on after button click.
my solved answer :
print.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takeScreenShot();
setContentView(R.layout.activity_main);
}
});

saving frame layout as bitmap with its subViews but imageView(subView) giving blackscreen

I have a framelayout.
it includes a button.
At runtime I click the button to pick an image from the gallery.
I create a imageView ,set the chosen image from the gallery on the imageView and add the imageView to framelayout.
then i save the entire view(framelayout) as a bitmap.
But the saved bitmap only shows the button and a black screen where the imageView should be.
I tried a lot of ways but could not resolve it...
pls help
public class MainActivity extends AppCompatActivity {
Button b;
RelativeLayout frame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button) findViewById(R.id.b);
frame = (RelativeLayout) findViewById(R.id.frame);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1 :
Uri selectedImage = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(
MainActivity.this.getContentResolver(), selectedImage);
} catch (IOException e) {
e.printStackTrace();
}
ImageView i = new ImageView(MainActivity.this);
i.setImageBitmap(bitmap);
frame.addView(i);
frame.invalidate();
Bitmap bitmapFromView = Bitmap.createBitmap(frame.getWidth(),frame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvass = new Canvas(bitmapFromView);
frame.draw(canvass);
saveBitmap(bitmapFromView);
break;
}
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
MediaScannerConnection.scanFile(getApplicationContext(),
new String[]{imagePath.getAbsolutePath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// TODO Auto-generated method stub
}
});
}
/*
also tried this...not working
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}
*/
}
Now finally i made a code working in most of the device i had tested
1) MainActivity.class
public class MainActivity extends AppCompatActivity {
private final int SELECT_PHOTO = 2;
private ImageView contactimage;
private LinearLayout content;
private TextView textall;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
content = (LinearLayout) findViewById(R.id.frame_save);
contactimage = (ImageView) findViewById(R.id.contactimage);
textall = (TextView) findViewById(R.id.textall);
textall.setText("MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst");
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
try {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
contactimage.setImageBitmap(selectedImage);
try {
content.setDrawingCacheEnabled(true);
content.setDrawingCacheEnabled(true);
content.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight());
content.buildDrawingCache(true);
Bitmap bitmap = getBitmapFromView(content);
content.setDrawingCacheEnabled(false);
File file, f = null;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
file = new File(android.os.Environment.getExternalStorageDirectory(), "Handcare");
if (!file.exists()) {
file.mkdirs();
}
f = new File(file.getAbsolutePath() + File.separator + "MyImage.png");
}
FileOutputStream ostream = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
private Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return returnedBitmap;
}
}
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#android:color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/frame_save">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:id="#+id/textall"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/contactimage"
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>
3) In manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
I did it.
I WAS ADDING THE IMAGE AND SAVING IT SEQUENTIALLY IN onActivityResult();
this:
ImageView i = new ImageView(MainActivity.this);
i.setImageBitmap(bitmap);
frame.addView(i);
frame.invalidate();
and this:
Bitmap bitmapFromView = Bitmap.createBitmap(frame.getWidth(),frame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvass = new Canvas(bitmapFromView);
frame.draw(canvass);
saveBitmap(bitmapFromView);
It seems that although the added image was visible to me on device but internally android had not processed it.And before that that could happen I was trying to save the view.
Now I finally solved it by adding the the imageView in onActivityResult();
and saving this view on a separate button click.
I also got positive result when I fired a worker thread which would sleep for 1 second after adding the imageview.
Then in postExecute() of the worker thread I saved the view as bitmap.

Create bitmap from two imageView with exact location

My Target:
Get one photo from camera or gallery, then set it to imageViewA
Add a draggable mask imageViewB on top of imageViewA
Users drag the mask imageViewB to anywhere in imageViewA
Users then click the save button
A combined bitmap of imageViewA and imageViewB should be created
My Problem:
Everything works fine, except that the imageViewB in the combined bitmap is not positioned appropriately (see the attached picture)
Code (MainActivity.java):
public class MainActivity extends ActionBarActivity {
Bitmap bmMask = null;
Bitmap bmOriginal = null;
Bitmap bmCombined = null;
ImageView normalImgView;
ImageView maskImgView;
ImageView combinedImgView;
static final int REQUEST_TAKE_PHOTO = 55;
static final int REQUEST_LOAD_IMAGE = 60;
String currentImagePath;
static final String TAG = "mover";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
combinedImgView = (ImageView) findViewById(R.id.combinedImgView);
normalImgView = (ImageView) findViewById(R.id.normalImgView);
maskImgView = (ImageView) findViewById(R.id.maskImgView);
bmMask = ((BitmapDrawable) maskImgView.getDrawable()).getBitmap();
Button addBtn = (Button) findViewById(R.id.addBtn);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bmCombined = ProcessingBitmap();
if(bmCombined!=null){
combinedImgView.setImageBitmap(bmCombined);
}
else {
Log.d(MainActivity.TAG, "combined bm is null");
}
}
});
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(MainActivity.TAG, "clicked");
getImageFromCameraIntent();
}
});
MultiTouchListener mTouchListener = new MultiTouchListener();
mTouchListener.isRotateEnabled = false;
// mTouchListener.isTranslateEnabled = false;
mTouchListener.isScaleEnabled = false;
maskImgView.setOnTouchListener(mTouchListener);
}
// take image from camera
private void getImageFromGalleryIntent() {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, REQUEST_LOAD_IMAGE);
}
// take image from camera
private void getImageFromCameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(this.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
// create a image file for storing full size image taken from camera
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentImagePath = image.getAbsolutePath();
Log.d(MainActivity.TAG, "photo path: " + currentImagePath);
return image;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
// photo returned from camera
// update UI
updatePhotoView(currentImagePath);
} else if (requestCode == REQUEST_LOAD_IMAGE && resultCode == Activity.RESULT_OK) {
// photo returned from gallery
// update UI
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = this.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
updatePhotoView(picturePath);
} else {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
}
}
// scale down the image, then display it to image view
private void updatePhotoView(String photoPath) {
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoPath, bmOptions);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, bmOptions);
bmOriginal = bitmap;
normalImgView.setImageBitmap(bmOriginal);
}
private Bitmap ProcessingBitmap(){
Bitmap newBitmap = null;
int w;
w = bmOriginal.getWidth();
int h;
h = bmOriginal.getHeight();
Bitmap.Config config = bmOriginal.getConfig();
if(config == null){
config = Bitmap.Config.ARGB_8888;
}
newBitmap = Bitmap.createBitmap(w, h, config);
Canvas newCanvas = new Canvas(newBitmap);
newCanvas.drawBitmap(bmOriginal, 0, 0, null);
Paint paint = new Paint();
float left = maskImgView.getLeft();
float top = maskImgView.getTop();
Log.d(MainActivity.TAG, "left is " + left);
Log.d(MainActivity.TAG, "top is " + top);
newCanvas.drawBitmap(bmMask, left, top, paint);
return newBitmap;
}
}
Code (xml)
<RelativeLayout
android:id="#+id/imgSection"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/background_dark">
<TextView
android:id="#+id/before_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="before combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/normalImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/maskImgView"
android:layout_centerInParent="true"
android:src="#drawable/daffodils"
android:layout_width="100dp"
android:layout_height="60dp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/holo_blue_dark">
<TextView
android:id="#+id/after_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="after combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/combinedImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Take Photo"
android:layout_gravity="center_horizontal"/>
<Button
android:id="#+id/addBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Combined Photo"
android:layout_gravity="center_horizontal"/>
My Thought:
I guess the positioning issue occurs in the few lines of code listed below. I just have no idea how to get it right, yet.
float left = maskImgView.getLeft();
float top = maskImgView.getTop();
newCanvas.drawBitmap(bmMask, left, top, paint);
Any help is appreciated!
In this case both of image view in same layout for ex.
<RelativeLayout
android:id="#+id/imgSection"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/background_dark">
<TextView
android:id="#+id/before_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="before combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/normalImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/maskImgView"
android:layout_centerInParent="true"
android:src="#drawable/daffodils"
android:layout_width="100dp"
android:layout_height="60dp" />
------->
RelativeLayout imgSection;
....
....
//On the save button click
imgSection.buildDrawingCache();
imgSection.getDrawingCache();//it will return combine image bitmap
I hope this will help.....

writing app to take a screenshot, and then save it to the gallery of my Android phone, but the saved screenshot is completely black

Here is my Screenshot class. The app is saving the screenshot in my gallery, which is what I want, but the image is completely black! If you had any suggestions to make this work, they would be much appreciated! Thanks!
public class Screenshot extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// set event listener for the Save Contact Button
Button button =
(Button) findViewById(R.id.button);
button.setOnClickListener(buttonClicked);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.screenshot, menu);
return true;
}
// responds to event generated when user clicks the Done Button
OnClickListener buttonClicked = new OnClickListener()
{
#Override
public void onClick(View v)
{
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
};
public void saveBitmap(Bitmap bitmap) {
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.LinearLayout01);
Bitmap b = Bitmap.createBitmap(mainLayout.getWidth(), mainLayout.getHeight(),
Bitmap.Config.ARGB_8888);
MediaStore.Images.Media.insertImage(getContentResolver(), b, "image.png" , "screenshot");
}
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
}
and here is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/LinearLayout01"
>
<Button
android:id="#+id/button"
android:layout_height = "wrap_content"
android:layout_width ="wrap_content"
android:text = "take screenshot"
android:onClick = "DoIt"
/>
<ImageView
android:id="#+id/eiffelTowerImageView"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_toRightOf="#+id/colosseumImageView"
android:src="#drawable/eiffeltower" />
</LinearLayout>
This Code Works like a Charm for me
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
Log.e("Screenshot", "taken successfully");
return b;
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory()
+ "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
Log.e("Screenshot", "saved successfully");
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
Get Activity in OnCreate()
Activity activity = (MainActivity) this;
Then Call these Function where ever you want
Bitmap bitmap = takeScreenShot(activity);
saveBitmap(bitmap);
Your solution will only work for taking a screenshot of your own app (since it uses the app's drawing cache), so if that's what you want to do, you'll have to make sure it's visible on the screen. Anything that your app doesn't have permission to view (like another app running behind it) will not show up or, as you're seeing, will show up black.
I suggest you look at this other screenshot question here to see the constraints under which you're working. Primarily, since you presumably don't have root permissions or a signature application (which would only be true if you compiled your own ROM), then you can't capture the framebuffer, which is what the native Android screenshot mechanism in 4.0+ can do for you if you press a specific key combination (on my Galaxy Nexus it's power+volume down).
Try this code :
public class MainActivity extends Activity {
Button btn_shoot;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn_shoot = (Button)findViewById(R.id.btn_shoot);
btn_shoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View view = findViewById(R.id.relativelayout);
view = view.getRootView();
view.setDrawingCacheEnabled(true);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap bitmap = view.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setBackgroundDrawable(bitmapDrawable);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
//we check if external storage is available, otherwise display an error message to the user
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Tutorial_ScreenShot");
directory.mkdirs();
String filename = "screenshot" + i + ".jpg";
File yourFile = new File(directory, filename);
while (yourFile.exists()) {
i++;
filename = "screenshot" + i + ".jpg";
yourFile = new File(directory, filename);
}
if (!yourFile.exists()) {
if (directory.canWrite())
{
try {
FileOutputStream out = new FileOutputStream(yourFile, true);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
Toast.makeText(MainActivity.this, "File exported to /sdcard/Tutorial_ScreenShot/screenshot" + i + ".jpg", Toast.LENGTH_SHORT).show();
i++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
else
{
Toast.makeText(MainActivity.this, "SD Card not available!", Toast.LENGTH_SHORT).show();
}
}
});
}
}

Categories

Resources