I was searching everywhere, but can't found solution...
I have two xml layouts for share.
I have inflated and assigned to the views correctly.
shareLayout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.share_every_for_self_game_layout, null);
contentView = (LinearLayout) shareLayout.findViewById(R.id.share_container_layout_id);
Problem is that the shared image is always empty.
Here is my code
private void shareResultToFacebook(){
try {
Bitmap bitmap = getBitmapFromView(contentView);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, getImageUri(this, bitmap));
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
}catch (Exception e){
e.getMessage();
}
}
//create bitmap from view and returns it
private Bitmap getBitmapFromView(View view) {
try {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(800, 600, Bitmap.Config.ARGB_8888);
//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 white background on the canvas
canvas.drawColor(Color.WHITE);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}catch (Exception e){
Global.logError("getBitmapFromView", e);
}
return null;
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(),
inImage, "", "");
return Uri.parse(path);
}catch (Exception e){
e.getMessage();
}
return null;
}
I found solution
I have changed my getBitmapFromView method body
private Bitmap getBitmapFromView(LinearLayout view) {
try {
view.setDrawingCacheEnabled(true);
view.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(600, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache(true);
Bitmap returnedBitmap = Bitmap.createBitmap(view.getDrawingCache());
//Define a bitmap with the same size as the view
view.setDrawingCacheEnabled(false);
return returnedBitmap;
}catch (Exception e){
Global.logError("getBitmapFromView", e);
}
return null;
}
And everything works fine ;)
private Bitmap getBitmapFromView(LinearLayout view) {
try {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(800, 600, Bitmap.Config.ARGB_8888);
//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 white background on the canvas
canvas.drawColor(Color.RED);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}catch (Exception e){
// Global.logError("getBitmapFromView", e);
}
return null;
}
Related
Basically, I want to take a screenshot of an entire scrollView. I've tried so many methods, but couldn't find the perfect one.
I've tried following:
public void takeScreenShot() {
mbitmap = getBitmapOFRootView();
createImage(mbitmap);
}
public void createImage(Bitmap bmp) {
String path = Environment.getExternalStorageDirectory().toString() + "/screenshot.jpg";
try {
FileOutputStream outputStream = new FileOutputStream(new File(path));
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Bitmap getBitmapOFRootView() {
mScrollView.setDrawingCacheEnabled(true);
int totalHeight = mScrollView.getChildAt(0).getHeight();
int totalWidth = mScrollView.getChildAt(0).getWidth();
mScrollView.layout(0,0, totalWidth, totalHeight);
mScrollView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mScrollView.getDrawingCache());
mScrollView.setDrawingCacheEnabled(false);
return b;
}
This method almost works, but it's just showing me only 2 views and a button, other than that whole screen is black:
my xml contains so many views, it's view hierarchy is something like this:
<ScrollView>
<ConstraintLayout>
<Views>
....
<Views>
</ConstraintLayout>
</ScrollView>
I've referred so many StackOverflow post, but it didn't work.
So can anybody help me with it?
Update:
Finally found a solution for it. So, it was an issue with the background, solved it by drawing canvas over it. Like below:
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return bitmap;
You should be using a canvas for the same
public static Bitmap saveBitmapFromView(View view, int width, int height) {
Bitmap bmp = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(canvas);
return bmp;
}
Taking and Sharing screenshot in android programmatically
I've searched everywhere but found this one working
takeAndShareScreenshot()
private void takeAndShareScreenshot(){
Bitmap ss = takeScreenshot();
saveBitmap(ss);
shareIt();
}
takeScreenshot()
private Bitmap takeScreenshot() {
View view = // decore view of the activity/fragment;
view.setDrawingCacheEnabled(true);
return view.getDrawingCache();
}
saveBitmap()
private void saveBitmap(Bitmap bitmap) {
// path to store screenshot and name of the file
imagePath = new File(requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + "name_of_file" + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
shareIt()
private void shareIt() {
try {
Uri uri = Uri.fromFile(imagePath);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/*");
String shareBody = getString(R.string.share_body_text);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, R.string.subject);
sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} catch (Exception e) {
e.printStackTrace();
}
}
Note:
In recent versions of android (>Marshmallow I guess), you may need `write
access to external directory`
I'm trying to capture all items in my ScrollView and save it as an image.
private void takeScreenShot()
{
ScrollView z = (ScrollView) findViewById(R.id.scroll_view);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap b = getBitmapFromView(u,totalHeight,totalWidth);
//Save bitmap
String extr = Environment.getExternalStorageDirectory()+"/Folder/";
String fileName = "report.jpg";
File myPath = new File(extr, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , 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;
}
The resulting image is enter image description here
There should be some text in the black area but it isn't showing.
If someone has a solution that may work, I would greatly appreciate it.
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
Just pass ScrollView or it's immediate child view to above function.
Try this, and let me know. Hope it will help !
Sometimes it'll set background to black if it isn't set to anything and it'll show up as black text on black background when you create the bitmap.
You can solve this by adding a background color in the .XML file. Be sure to add a background color to the view you want to capture and each item within the views as well. Anything that doesn't have a set background will show up with a black background.
I am trying to save part of my Activity, without Toolbar and Statusbar. The code that i have right now, saves the whole screen. Please refer to the image below.
Code that i have right now:
llIDCardRootView = (LinearLayout) view.findViewById(R.id.ll_id_card_root_view);
llIDCardContainer = (LinearLayout) llIDCardRootView.findViewById(R.id.ll_id_card_view);
private void createBitmap() {
Log.d(Const.DEBUG, "Creating Bitmap");
Bitmap bmp;
//View v = llIDCardContainer.getRootView();
//View v = activity.getWindow().getDecorView().findViewById(android.R.id.content);
//View v = activity.findViewById(R.id.ll_id_card_root_view);
ViewGroup v = (ViewGroup) ((ViewGroup) activity
.findViewById(android.R.id.content)).getChildAt(0);
v.setDrawingCacheEnabled(true);
// v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
// v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
// v.buildDrawingCache(true);
bmp = Bitmap.createBitmap(v.getDrawingCache());
File directory = new File(Environment.getExternalStorageDirectory()
+ File.separator);
File file = new File(directory, FILE_NAME);
try {
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
v.destroyDrawingCache();
v.setDrawingCacheEnabled(false);
}
The image that is being saved..
How can i just save the part that i need from the fragment?
Use function below to save any view to image file. If you need to save in Fragment, call below function in fragment.
public static Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//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 white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
Use this
container_layout.setDrawingCacheEnabled(true);
container_layout.buildDrawingCache(true);
Bitmap saveBm = Bitmap.createBitmap(container_layout.getDrawingCache());
container_layout.setDrawingCacheEnabled(false);
You can now save the saveBm as file
you have to make a separate view for save this as image and then you can pick screenshot of that view like:
LinearLayout content = findViewById(R.id.rlid);
content.setDrawingCacheEnabled(true);
Bitmap bitmap = content.getDrawingCache();
File file,f;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
file =new File(android.os.Environment.getExternalStorageDirectory(),"TTImages_cache");
if(!file.exists())
{
file.mkdirs();
}
f = new File(file.getAbsolutePath()+file.seperator+ "filename"+".png");
}
FileOutputStream ostream = new FileOutputStream(f);
bitmap.compress(CompressFormat.PNG, 10, ostream);
ostream.close();
}
catch (Exception e){
e.printStackTrace();
}
and not to forgot add permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
When I get the bitmap from the DrawingCache of a view I get no error but I don't see a valid bitmap either. What am I doing wrong?
The code I use to generate the bitmap:
SharePhotoView sharePhotoView = SharePhotoView_.build(this);
sharePhotoView.bind(mCatch);
sharePhotoView.setDrawingCacheEnabled(true);
sharePhotoView.buildDrawingCache();
Bitmap bitmap = sharePhotoView.getDrawingCache();
catchImage.setImageBitmap(bitmap);
The code I use to make the view:
#EViewGroup(R.layout.share_photo)
public class SharePhotoView extends LinearLayout{
#ViewById
ImageView catchImage;
public SharePhotoView(Context context) {
super(context);
}
public void bind(Catch catchItem) {
Bitmap bitmap = BitmapFactory.decodeFile(catchItem.getImage().getPath());
catchImage.setImageBitmap(bitmap);
}
}
Use this code for a Bitmap from view:
Bitmap bitmap;
try {
bitmap = Bitmap.createBitmap(YOUR_VIEW.getWidth(), YOUR_VIEW.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
YOUR_VIEW.draw(canvas);
File root = Environment.getExternalStoragePublicDirectory(Environment.PICTURES);
String fname = "NAME_OF_FILE.jpg";
file = new File(root, fname);
try {
if (!root.exists()) {
root.mkdir();
}
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
YOUR_VIEW.destroyDrawingCache();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
Found a method somewhere that did the trick:
public static Bitmap getScreenViewBitmap(View v) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
Source: http://www.jattcode.com/getting-bitmap-from-a-view-visible-invisible-oncreate/
I'm attempting to save all of the icons of the packages on a device as a BMP or PNG file by iterating through each package and doing the following.
Drawable icon = getPackageManager().getApplicationIcon(packageInfo);
Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
try {
out = new FileOutputStream("/storage/sdcard0/images/" + packageInfo.packageName +".png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
out.close();
} catch(Throwable ignore) {}
}
This is creating blank images though, how would I change my code to create the actual icon in an image format?
My issue was this if anyone has the same problem, I referenced this answer.
I forgot to check to see if the icon was already an instance of BitmapDrawable. Because it was I could just cast it to a bitmapdrawable and use .getBitmap
if (icon instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable)icon).getBitmap();
}else{
bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
}
Below is the code that could cover all the cases.
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
return Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
}