I have a webview with built in zoom-controls how to capture screenshot with full zoomed out webview and how to implement custom zoom in and out button.
To get View's drawing cache you can use this code:
public static Bitmap getBitmapFromView(View view) {
Bitmap bmp = Bitmap.createBitmap(view.getLayoutParams().width, view.getLayoutParams().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;
}
Then convert bitmap to PNG/JPG:
OutputStream stream = new FileOutputStream("/sdcard/test.png");
bitmap.compress(CompressFormat.PNG, 100, stream);
stream.close();
This should work.
Related
I have a texture view on which a video is getting played. I need to take screenshot of the frame of playing video. Earlier I was using a method
public Bitmap getFrameAsBitmap() {
Bitmap bmp = textureview.getBitmap();
Canvas canvas = new Canvas(bmp);
textureview.draw(canvas);
return bmp;
}
It is working fine on most of the devices but on Samsung M series I can not take screenshot. Only black screen is coming.
Then I tried
public Bitmap getFrameAsBitmap() {
View view = textureview;
view.setDrawingCacheEnabled(true);
Bitmap bmp = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
textureview.draw(canvas);
return bmp;
}
But this method is not returning data on any phone. Any ideas what to do?
Here are several things that you can try.
Return the bitmap directly.
public Bitmap getFrameAsBitmap() {
return textureview.getBitmap();
}
Clone the bitmap then return the clone.
public Bitmap getFrameAsBitmap() {
Bitmap bmp = textureview.getBitmap();
Bitmap clone = bmp.copy(Bitmap.Config.ARGB_8888, true);
return clone;
}
Draw the bitmap on a new canvas.
public Bitmap getFrameAsBitmap() {
Bitmap bmp = textureview.getBitmap();
//Try using bitmap's width/height first, if it does not work, use view's width/height instead.
Bitmap newBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);
//Bitmap newBmp = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBmp);
//It is not efficient to create a Paint object too often. Better make it as global variable.
canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.ANTI_ALIAS_FLAG));
return newBmp;
}
I have to convert com.google.mlkit.vision.common.InputImage to equivalent Bitmap image in android using Java. Right now I am using the following code.
// iImage is an object of InputImage
Bitmap bmap = Bitmap.createBitmap(iImage.getWidth(), iImage.getHeight(), Bitmap.Config.RGB_565);
bmap.copyPixelsFromBuffer(iImage.getByteBuffer());
The above code is NOT converting the InputImage to Bitmap. Can anyone please suggest me the efficient way of converting InputImage to Bitmap.
You can create bitmap from byteBuffer, that can be received by call the method getByteBuffer().In the offical quick start example of ML Kit Vission you can find the vay how to achieve this. Below is a piece of code that can solve your problem:
Method getBitmap() thats converts NV21 format byte buffer to bitmap:
#Nullable
public static Bitmap getBitmap(ByteBuffer data, FrameMetadata metadata) {
data.rewind();
byte[] imageInBuffer = new byte[data.limit()];
data.get(imageInBuffer, 0, imageInBuffer.length);
try {
YuvImage image =
new YuvImage(
imageInBuffer, ImageFormat.NV21, metadata.getWidth(), metadata.getHeight(), null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, metadata.getWidth(), metadata.getHeight()), 80, stream);
Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
stream.close();
return rotateBitmap(bmp, metadata.getRotation(), false, false);
} catch (Exception e) {
Log.e("VisionProcessorBase", "Error: " + e.getMessage());
}
return null;
}
Method rotateBitmap():
private static Bitmap rotateBitmap(
Bitmap bitmap, int rotationDegrees, boolean flipX, boolean flipY) {
Matrix matrix = new Matrix();
// Rotate the image back to straight.
matrix.postRotate(rotationDegrees);
// Mirror the image along the X or Y axis.
matrix.postScale(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
Bitmap rotatedBitmap =
Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
// Recycle the old bitmap if it has changed.
if (rotatedBitmap != bitmap) {
bitmap.recycle();
}
return rotatedBitmap;
}
The full code can be seen by clicking on the link: https://github.com/googlesamples/mlkit/blob/master/android/vision-quickstart/app/src/main/java/com/google/mlkit/vision/demo/BitmapUtils.java
Is there a way to take a screenshot of a video playing in video view. I searched on the forum but could not get the required info. I tried with
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
and
mCustomVideoView.setDrawingCacheEnabled(true);
Bitmap videoView = mCustomVideoView.getDrawingCache(false);
But none of these methods were helpful.
Just make it with that:
videoview.buildDrawingCache();
Bitmap bitmap = yourvideoview.getDrawingCache();
java.io.ByteArrayOutputStream stream=new java.io.ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream);
byte[] videoByteArray=stream.toByteArray(); String video_str = Base64.encodeToString(videoByteArray, 0);
The output is the String video_str and the Bitmap bitmap.
here tempdata is the data captured from camera, savephoto(Bitmap) is a method am using to save the image taken from camera, and it is executing accurately ,,
BUt on [2]
i am overlaying another bitmap ,, and when i am calling the savephoto(p)
it is creating an empty file in the memorycard ...
not saving any image.
how can i overlay the two bitmap on top of each other
[1]File Imgname = Environment.getExternalStorageDirectory();
Bitmap bmp = BitmapFactory.decodeByteArray(tempdata,0,tempdata.length);
imv.setImageBitmap(bmp);
savePhoto(bmp);
[2]Bitmap bmp2 = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
Bitmap b = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
canvas.drawBitmap(bmp, 0,0, null);
canvas.drawBitmap(bmp2, 50, 50, null);
savePhoto(b);
any help will be greatly appreciated
thanx
you can do like this after getting after getting bitmap from camera (assume bitmap1) and your bitmap to overlay on top of bitmap1 (assume bitmap2)
call this overlayMark() with your bitmaps it will return overlay bitmap that is your required bitmap . you can save that bitmap..
private Bitmap overlayMark(Bitmap bmp1, Bitmap bmp2) {
int bh = originalBitmap.getHeight();
int bw = originalBitmap.getWidth();
Bitmap bmOverlay = Bitmap.createBitmap(bw,bh,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, 0,0, null);
return bmOverlay;
}
There's say some ImageView object. I want to read bits/raw data of this object as InputStream. How to do that?
First get background image of the ImageView as an object of Drawable:
iv.getBackground();
Then convert Drawable image into Bitmap using
BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bitmap = bitDw.getBitmap();
Now use ByteArrayOutputStream to get the Bitmap into a Stream and get bytearray[]; then
convert the bytearray into a ByteArrayInputStream.
You can use the following code to get InputStream from ImageView.
Full Source code
ImageView iv = (ImageView) findViewById(R.id.splashImageView);
Drawable d = iv.getBackground();
BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bitmap = bitDw.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] imageInByte = stream.toByteArray();
System.out.println("........length......" + imageInByte);
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
Thanks
Deepak
These methods below are useful because they work with any kind of Drawable (not only BitmapDrawable). If you want to use drawing cache as in David Caunt's suggestion, consider using bitmapToInputStream instead of bitmap.compress, because it should be faster.
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static InputStream bitmapToInputStream(Bitmap bitmap) {
int size = bitmap.getHeight() * bitmap.getRowBytes();
ByteBuffer buffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(buffer);
return new ByteArrayInputStream(buffer.array());
}
You can use the drawing cache to retrieve a Bitmap representation of any View class.
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
Then you can write the bitmap to an OutputStream, for example:
b.compress(CompressFormat.JPEG, 80, new FileOutputStream("/view.jpg"));
In your case I think you can use a ByteArrayOutputStream to get a byte[] from which you can create an InputStream. The code would be something like this:
ByteArrayOutputStream os = new ByteArrayOutputStream(b.getByteCount());
b.compress(CompressFormat.JPEG, 80, os);
byte[] bytes = os.toByteArray();
You might be looking for this:
openRawResource