View.draw(canvas) poor quality of child views - android

I am trying to solve problem when I get bitmap from view (with bad quality of childviews) and store it as PNG. There are some taken pictures using this code:
Bitmap b = Bitmap.createBitmap(
Math.round(General.getDisplayWidthPx()), Math.round(General.getDisplayHeightPx()), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas( b );
wallFrame.invalidate();
wallFrame.draw( canvas );
FileOutputStream out = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
When the childview is small the quality of childview is terrible.
But when it's larger the quality is better.
As you can see the smaller the picture, the lower the quality. I also tried deprecated methods:
wallFrame.setDrawingCacheEnabled(true);
Bitmap b = wallFrame.getDrawingCache();
wallFrame is ZoomLayout which extends RelativeLayout. Child views in wallFrame are SubScalingImageView which extends View. I think it's not caused by SubScalingImageView I've tried standard ImageView and result was the same. When I take screenshot of app, the result is better.
Pictures are loaded from user storage using Uri (so not from drawable). SubscalingImageView has own decoders. In app the quality of pictures is perfect.
I think problem is somewhere in view.draw(canvas). But I have no idea how to edit it to make it work.
I appreciate every idea. Thank you!

Related

Take screen shot from web view in android

I have a web view that I need to take a screenshot from a site. People suggested me use the function capturePicture(), this function is deprecated. So I create bitmap from current site like this and save it as byte[ ] to the database:
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getWidth(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, stream);
DatabaseHelper.updateData(id, stream.toByteArray());
bitmap.recycle();
And load it in another Activity with Glide:
Glide.with(context).load(items.get(position).getImage())
.placeholder(R.drawable.ic_defualt)
.into(holder.ivShot);
Now, If the number of screenshots increases, The speed of the app decreases and Memory size increases. I know that the issue of bitmaps is very complicated, But there must be a way to take a picture of the web view without any memory leaks or slowdowns.
I try to use threads to get bitmap but it doesn't help. Anyone know How I can do it?

drawing cache returns the same Image

i have problem with frame layout drawing cache.
i capture the video from camera and display it in frame layout.
i want to read this image(s) and send it to another client with TCP or UDP.
now the problem is the cache dosent update and i have the same image (complete black image) always
here is my code:
selfImage.setDrawingCacheEnabled(true);
selfImage.buildDrawingCache();
mainImage = selfImage.getDrawingCache();
Bitmap bmp = mainImage.copy(Bitmap.Config.ARGB_8888,false);
streamImage.reset();
bmp.compress(Bitmap.CompressFormat.JPEG, 50, streamImage);
Bitmap temp = bmp;
runOnUiThread(new uiInterface(12, temp));
sendVideo(streamImage);
selfImage.destroyDrawingCache();
mainImage.recycle();
selfImage.setDrawingCacheEnabled(false);
self image is my frame layout!
please help me.
thanks
I used this code. It works in my case.
setDrawingCacheEnabled(true);
destroyDrawingCache();
return getDrawingCache();

Android saving webview to gallery, intermediate bitmap is too big

I am trying to write a method in android to save the whole webview as an image as following:
bitmap = Bitmap.createBitmap(webView.getWidth(),
Math.round(webView.getContentHeight() * webView.getScale()), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, JPEG_COMPRESSION, out);
However, the bitmap is too big (more than 100 MB) and takes too much memory. Does anyone know any better method to keep the memory usage low?
The problem is the WebView is small, and the generated JPEG file is small but the intermediate Bitmap which is not used any more in other places is huge.
Set JPEG_COMPRESSION = 0-100 as it is a quality paramater of bitmap 0 meaning compress for small size, 100 meaning compress for max quality.
You can also set bitmap height and width using
BitmapFactory.Options bop
bop.outWidth
bop.outHeight

Android OOM when creating bitmap from view

i am creating a bitmap of layout. Its working fine in most of the devices but in few samsung devices, its throwing OOM. Below is the code I am using to convert the layout to bitmap
private void enableViewCache() {
viewToConvert.setDrawingCacheEnabled(true);
viewToConvert.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.AT_MOST));
viewToConvert.buildDrawingCache(true);
}
public Bitmap getBitmapFromView() {
Bitmap b = Bitmap.createBitmap(viewToConvert.getDrawingCache());
viewToConvert.setDrawingCacheEnabled(false);
viewToConvert.destroyDrawingCache();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
return b;
}
I am getting OOM at Bitmap.createBitmap call. I have checked most of the OOM bitmap issues in stackoverflow which mentioned about using sampling and all but I dont know how to implement that in this usecase.
I'm not sure what you're trying to accomplish, but in MOST cases you don't want to extract a Bitmap from a View. What you usually want is to maintain the bitmap on a different place (LRU Cache maybe?). My guess would be the view's drawing cache is the issue.
Anyway, the problem is probably the way you're handling a large bitmap. Read this article so you know how to sample, scale down, and other techniques so you don't get OOM.

Android custom view save visible screen to bitmap

In my app the user manipulates a image, rotates, pinch, zoom etc. This is make within onDraw() using canvas.translate(), canvas.rotate() etc. Of course the image is big and after the manipulation of the image the user performs interactions with other Views. The thing is I don't want to redraw the whole big image over and over again only the visible part. So I'd like, after the user finishes operations, SAVE the current VISIBLE image on the screen to memory/bitmap/cache and redraw only that.
How can I achieve this ?
In the constructor of your custom View, enable the drawing cache like this: setDrawingCacheEnabled(true);. Then whenever you want to save the state of your Canvas you can call getDrawingCache(), which returns the desired Bitmap.
Documentation: getDrawingCache()
In your on draw initialize your Canvas with a bitmap.
keep a reference of this bitmap and save it whenever required.
I've found a really great article about what I needed HERE
To kepp thing clear, first I need to create a bitmap with the size of my View, then create a canvas for it, draw on canvas and then save it.
public void saveScreenshot() {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.draw(myGiganticImage)
File file = new File(context.getFilesDir() + "/cache.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
cachedBackground = BitmapFactory.decodeFile(context.getFilesDir() + "/cache.jpg"
invalidate()
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
I simply call this on onDraw() when I need it. It will save a bitmap on internal memory which I can use to draw, instead of the big picture.
Following may help you :
(1)
View v = view.getRootView();
v.setDrawingCacheEnabled(true);
Bitmap b = v.getDrawingCache();
(2) This is a similar to another question at How to capture the android device screen content?
(3) You can try using this library
http://code.google.com/p/android-screenshot-library/ It introduces an Android Screenshot Library (ASL) which enables to programmatically capture screenshots from Android devices without requirement of having root access privileges.

Categories

Resources