I am aware that not all Android devices can take screen shots, but I would like to be able to take screen shots of my users game screen programmatically so they can share it with friends etc. Kinda like Hill Climb racing does in there game.
Does anyone know how to do this? I tried a few solutions that are posted on here:
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + ACCUWX.IMAGE_APPEND;
// create bitmap screen capture
Bitmap bitmap;
View v1 = activity.getCurrentFocus().getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
imageFile = new File(mPath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But no luck. Any other way to do this? Maybe a new method.
EDIT:
I am getting a null pointer at line View v1 = activity.getCurrentFocus().getRootView();
Try This In this I take screen shot of current layout and save in sdcard...
To Capture Screen Shoot
Use
View v1 = getWindow().getDecorView().getRootView();
in place of
View v1 = activity.getCurrentFocus().getRootView();
it will not throws Null Pointer Exception.
Enjoy!!
Related
I want to take screenshot of my WebView by clicking on menu item . And then I want to draw on this screenshot and save it on my sdcard.
I've also found the solution of taking screenshot and saving. Here it is:
private void getScreen(View content) {
Bitmap bitmap = content.getDrawingCache();
File file = new File("/sdcard/screen.png");
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
and on onOptionsItemSelected() method:
View content = findViewById(R.id.webview_main);
content.setDrawingCacheEnabled(true);
getScreen(content);
It`s work ok, but I want to implement drawing on it too. If anyone know, how to do this, tell me please,
I will be very grateful.
i am working on OpenGl Es in android.given efects on images and when i save the image in sdcard it showing black image.how i solve this problem.
File cacheDir;
Toast.makeText(ImageProcessingActivity.this, "Photo", 500).show();
Bitmap icon;
frame.setDrawingCacheEnabled(true);
icon = Bitmap.createBitmap(frame.getDrawingCache());
Bitmap bitmap = icon;
frame.setDrawingCacheEnabled(false);
// File mFile1 = Environment.getExternalStorageDirectory();
Date d = new Date();
String fileName = d.getTime() + "mg1.jpg";
File storagePath = (Environment.getExternalStorageDirectory());
File dest = new File(storagePath + "/CityAppImages");
if (!dest.exists()) {
dest.mkdirs();
}
File mFile2 = new File(dest, fileName);
sdpath = mFile2.getAbsolutePath();
Log.d("qqqqqqqqqqqqqqqqqqqqqqq", "zzzzzzzz" + sdpath);
try {
FileOutputStream outStream;
outStream = new FileOutputStream(mFile2);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(ImageProcessingActivity.this, "Photo Saved Sucessfully", 500)
.show();
image.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ImageProcessingActivity.this, "Photo Not Saved Sucessfully",500).show();
}
I had this problem once and it was because getDrawingCache is not what it should be. The problem is not the saving, is the way you do it.
From what I understand you want to capture the screen of your app, but this is very tricky and can cause a lot of problems.
Read this topic, since it helped me a lot when I had this problem.
How to programmatically take a screenshot in Android?
Edit:
Also, because you are using GLES and then printing the screen you should go to Settings > Developer Options > check Disable Hardware Overlays and Force GPU Rendering.
I want to programatically take screen shot of my game, just as you'd get in Eclipse DDMS.
Screenshot taken through the solution proposed here: How to programmatically take a screenshot in Android? and in most other SO questions only have View elements visible, but not the SurfaceView.
SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get root view
View view = activity.getWindow().getDecorView().getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d("ScreenShot", "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any help in this regard would be highly appreciated. Thanks.
I hope this also useful for you. here little difference for the above answer is
for I used glsurfaceview to take the screen shots hen i click the button.
this image is stored in sdcard for mentioned folder :
sdcard/emulated/0/printerscreenshots/image/...images
My Program :
View view_storelayout ;
view_storelayout = findViewById(R.id.gl_surface_view);
button onclick() {
view_storelayout.setDrawingCacheEnabled(true);
view_storelayout.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(view_storelayout.getDrawingCache());
view_storelayout.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 90, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
final Calendar c=Calendar.getInstance();
long mytimestamp=c.getTimeInMillis();
String timeStamp=String.valueOf(mytimestamp);
String myfile="hari"+timeStamp+".jpeg";
dir_image=new File(Environment.getExternalStorageDirectory()+
File.separator+"printerscreenshots"+File.separator+"image");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "myPath:"
+dir_image.toString(), Toast.LENGTH_SHORT).show();
Log.v("hari", "screenshots:"+dir_image.toString());
}
Note :
But, here i am faced one problem. In this surfaceview , i drawn line and circle
at runtime. after drawn some objects, when i take screenshots , its stored only for
black image like surfaceview is stored as an image.
And also i want to store that surfaceview image as an .dxf format(autocad format).
i tried to stored image file as an .dxf file format.its saved successfully in
autocad format. but, it cant open in autocad software to edit my .dxf file.
The code from the Usman Kurd answer will not work is most cases.
Unless you're rendering H.264 video frames in software with Canvas onto a View, the drawing-cache approach won't work (see e.g. this answer).
You cannot read pixels from the Surface part of the SurfaceView. The basic problem is that a Surface is a queue of buffers with a producer-consumer interface, and your app is on the producer side. The consumer, usually the system compositor (SurfaceFlinger), is able to capture a screen shot because it's on the other end of the pipe.
Take Screenshot of SurfaceView
I'm making a gallery in which I load (on run time) images from asset folder. Now I want to save image to SD card on the click event.
For example: When the app starts, the user see images, they can scroll through images and view them (this part is done). The problem is pictures are loading dynamically in my own gallery view. I have not hard coded them.
I want to save it to the SD card. But I don't have the hard coded path of images. There can be any number of images.
private void CopyAssets() {
AssetManager assetManager = getAssets();
InputStream in=null;
String[] files = null;
try {
files = assetManager.list("image");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(String filename : files) {
try {
in = assetManager.open(filename);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
String dirName = Environment.getExternalStorageDirectory().toString();
File newFile = new File(dirName);
newFile.mkdirs();
OutputStream out = new FileOutputStream(newFile);
System.out.println("in tryyyy");
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
I tried above method, I don't want to copy all the image to the SD card. But only that one which the user chooses from the gallery that too dynamically. As there will be a number of images. Hard coding each image path will be tough.
Is there any way in Android, by which I can get the current image path or URI in a string? What is View v = this.getCurrentFocus();? What does it return?
a Gallery extends from AdapterView , and just like on adapterView , you can add a listener for when an item is being selected.
one you know which item was selected , use it in order to copy the image you want to the sd-card.
for better understanding of how to implement the adapter for the adapterView , watch "the world of listView" video . you might want to put the path into the viewHolder (depending on your code and design) .
Here's a method I created that will allow you to save an image (Bitmap) to the memory. The parameters requiere a bitmap object and the filename of that object.
public void writeBitmapToMemory(String filename, Bitmap bitmap) {
FileOutputStream fos;
// Use the compress method on the Bitmap object to write image to the OutputStream
try {
fos = this.openFileOutput(filename, Context.MODE_PRIVATE);
// Writing the bitmap to the output stream
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
I hope this helps.
The idea of my app is to capture image from camera then crop specified area from it.
The problem :
When i save the cropped image in my sd card for the first time to launch the app, it saved properly. but when run my app one more time and take image then crop it. when save it the first image that take and crop at first time appear in the sd card not the current one.
This is my code for save images:
public static void save(Activity activity, Bitmap bm, String name) {
OutputStream outStream = null;
File externalFilesDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File outFile = new File(externalFilesDir, "IDOCR" + File.separator + "Numbers");
if (!outFile.exists())
outFile.mkdirs();
File number = new File(outFile, name + ".PNG");
//if (number.exists())
// number.delete();
try {
//outStream = new FileOutputStream(new File(path));
outStream = new FileOutputStream(number);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
bm.recycle();
System.gc();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Maybe if you are trying to overwrite the previous version of the file, you should first delete the previous one...
You can add:
if (!outFile.exists())
outFile.mkdirs();
else {
outFile.delete();
outFile.createNewFile();
}