My application is a launcher, now I need a bitmap of current view.
Launcher's view can be retrived by getDrawingCache(), like following
Bitmap bitmap = Bitmap.createBitmap(screen_w, screen_h, Config.ARGB_8888 );
View decorview = getWindow().getDecorView();
decorview.setDrawingCacheEnabled(true);
bitmap = decorview.getDrawingCache();
But the bitmap is only of launcher'view, NOT containing wallpaper.
How can I get the bitmap with wallpaper ?
OK, I had to say there is NO single API provide this function, user has to compound two bitmap, one is wallpaper part, the other is launcher's desktop view.
Generally, launcher extends wallpaper to several screens, so we have to get wallpaper's visible part.
Following is how I do:
//get wallpaper's visible part
//#param screenCount how many screens launcher has
//#param screenCurrent current screen index
Bitmap wallpaper =
((BitmapDrawable) WallpaperManager.getInstance(context).getDrawable()).getBitmap();
float step = 0;
step = (wallpaper.getWidth() - w) / (screenCount - 1);
Bitmap wallpaperCurrent =
Bitmap.createBitmap(wallpaper, (int)(screenCurrent * step), 0, w, h);
//get launcher's visible view bitmap
View decorview = context.getWindow().getDecorView();
decorview.buildDrawingCache();
Bitmap desktopBitmap = decorview.getDrawingCache();
//compound bitmaps
Bitmap compoundBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(compoundBitmap);
canvas.drawBitmap(wallpaperCurrent, 0, 0, null);
canvas.drawBitmap(desktopBitmap, 0, 0, null);
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
// return compoundBitmap
Related
I'm creating free activity monitoring app similar to Strava. Using vtm-android as map library.
I would like save org.oscim.android.MapView as image, without rendering it to screen.
I found several solutions, how to save view as image, but unfortunately none of them is working when when view is not "attached" to existing component tree.
My expectation was to initialize MapView like this:
final String MAP_FILE = "somemap.map";
MapView mapView = new MapView(mContext);
final org.oscim.map.Map map = mapView.map();
MapFileTileSource tileSource = new MapFileTileSource();
String mapPath = new File(Environment.getExternalStorageDirectory(), MAP_FILE).getAbsolutePath();
if (tileSource.setMapFile(mapPath)) {
// Vector layer
VectorTileLayer tileLayer = map.setBaseMap(tileSource);
// Render theme
map.setTheme(VtmThemes.DEFAULT);
double latitude = 49.1625214;
double longitude = 20.2644075;
// Note: this map position is specific to Berlin area
map.setMapPosition(latitude, longitude, 1 << 12);
}
mapView.layout(0, 0, 200, 200);
//Get the dimensions of the view so we can re-layout the view at its current size
//and create a bitmap of the same size
int width = view.getWidth();
int height = view.getHeight();
int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
//Cause the view to re-layout
view.measure(measuredWidth, measuredHeight);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
//Create a bitmap backed Canvas to draw the view into
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
view.draw(canvas);
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(byteBuffer);
//save bytes from bytebuffer to file or db
But instead of map image, I get full transparent image.
To take screen shot you need render it on screen. Without rendering screenshot is not possible
mapView.getDrawingCache()
It will return you bitmap of current displaying.
Bitmap capturedScreen = Bitmap.createBitmap(mapView.getDrawingCache()); imageView.setImageBitmap(capturedScreen);
Here 'capturedScreen' will give you image of mapview.
I have a list of items where I am displaying a bitmap next to the item's name. This bitmap is to be created from 2 images, I have a background image with a smaller foreground image to add on top of the background.
I am seeing that the background image appears to not be present on some of my rows in my list. It is not consistent when and which row has the combined bitmap without the background. It is not always the same row where the combined bitmap does not have the background and it is not always the first or not always the last row where the bitmap does not have the background. And sometimes the whole list has every row with the correct image.
The image below is a mockup showing my issue.
My code for creating the combined bitmap is as follows.
Bitmap combinedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas combinedCanvas = new Canvas(combinedBitmap);
// Add the first bitmap to the canvas (this is my background and this is what appears to be
// missing on some rows in my list on some occasions)
combinedCanvas.drawBitmap(backgroundBitmap, 0, 0, null);
// my second smaller image, on top of the first image but 1 pixel in
// from the left and 20 pixels down from the top
combinedCanvas.drawBitmap(foregroundBitmap, 1, 20, null);
return combinedBitmap;
Note: My backgroundBitmap is generated from a Drawable using the following code
Bitmap backgroundBitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getMinimumHeight(),
Bitmap.Config.ARGB_8888);
backgroundBitmap.setDensity(resources.getDisplayMetrics().densityDpi);
Canvas canvas = new Canvas(backgroundBitmap);
drawable.draw(canvas);
Any suggestions of what I have wrong or even where to look to try and resolve this would be greatly appreciated.
EDIT: I have tested adding a colour to the background of my combinedCanvas to try and see where the image generation is going wrong by adding the following code
// TEMP: fill the canvas in red for now so I can see which combinedBitmaps are missing
// the background image
combinedCanvas.drawColor(Color.RED);
Now the rows which do not have the background are coloured in red. This indicates that the code above to create the combined canvas is somehow not adding the backgroundBitmap. I have checked and my background image is not null for every row in my list.
This method works fine for me. It's in C# (Xamarin), you'll have to translate it to Java I'm afraid.
public static Bitmap CombineImages(Bitmap background, Bitmap foreground)
{
int width = background.Width, height = background.Height;
Bitmap cs = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
Canvas comboImage = new Canvas(cs);
background = Bitmap.CreateScaledBitmap(background, width, height, true);
comboImage.DrawBitmap(background, 0, 0, null);
int top = (int)(0.05 * height);
int left = (int)(width - (foreground.Width + (width * 0.05)));
comboImage.DrawBitmap(foreground, left, top, null);
return cs;
}
The left and top are hardcoded for my requirements, it would be better to pass them in as arguments.
Is there possible to overlay an image on camera preview butt that image for example a coin should look like an original view, as I will move my camera it will remains in its place just like real objects as seen in camera.
I have done with overlaying a static image on camera preview but that's not my requirement.
please suggest.
thanks.
to overlay an image up to another image use this method.
public Bitmap overlayChange(Bitmap all, Bitmap scaledBorder) {
final int width = change.getWidth();
final int height = change.getHeight();
all = Bitmap.createScaledBitmap(change, width, height, true);
Bitmap mutableBitmap = all.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
scaledBorder = Bitmap.createScaledBitmap(border, width, height, true);
canvas.drawBitmap(scaledBorder, 0, 0, null);
return mutableBitmap;
}
and to use it simple
yourBitmap = overlayChange(yourBitmap , YourOtherBitmap);
well i'v problem with canvas.draw() i'm having multiple frames to overlay on the same bitmap . and i succeed to do this. but the problem is when now it comes to apply another frame using the same methods but different border , the border overlay the old ones.
void hm(){
Bitmap border = BitmapFactory.decodeResource(getResources(), R.drawable.vignette2);
int width = bmp.getWidth();
int height = bmp.getHeight();
change = Bitmap.createScaledBitmap(change, width, height, false);
Canvas canvas = new Canvas(change);
Bitmap scaledBorder = Bitmap.createScaledBitmap(border,width,height, false);
canvas.drawBitmap(scaledBorder, 0, 0,null);
//canvas.drawBitmap(k, 0, 0, null);
view.setImageBitmap(change);
}
and here is the other method:
void hm1(){
Bitmap border = BitmapFactory.decodeResource(getResources(), R.drawable.white);
int width = bmp.getWidth();
int height = bmp.getHeight();
change = Bitmap.createScaledBitmap(change, width, height, false);
Canvas canvas = new Canvas(change);
Bitmap scaledBorder = Bitmap.createScaledBitmap(border,width,height, false);
canvas.drawBitmap(scaledBorder, 0, 0,null);
//canvas.drawBitmap(k, 0, 0, null);
view.setImageBitmap(change);
}
now when i click on button1 the overlay applies to the view. and when i click on button2 it also applies to the view but it doesn't destroy the old border("the Overlay image").
i know that i should use different bitmap to handle every view of the imageview. but i'm using save button which will save the Bitmap change which means i want to apply the borders on this image and display it. without overlaying the old borders.
for example i'm using QuickActionand here is how i'm trying to accomplish the clicks.
if (actionId == border0){
hm();
}
if (actionId == border1 ){
hm1();
}
if (actionId == border2 ){
}
it works but as i said it overlay the old ones .
any help will be thankful.
thanks in advance.
Solved it tomorrow i will post the Answer :).
Well you create a new bitmap based on the old one with this line:
change = Bitmap.createScaledBitmap(change, width, height, false);
So make sure that you somehow reset the change bitmap with the original:
change = Bitmap.createScaledBitmap(originalBitmap, width, height, false);
I wanted to create an app by taking images from the sd card and add caption to it. Also I wanted to move the caption as per our wish and place it somewhere as desired and save it .can you please suggest an idea for doing this. Also if we want to add a caption to the existing image from SD card then , do we need to have database for doing this. or can it be saved directly to the SD card.
Refer This Answer
You can put an EditText and Write into it and after writting you first convert it to Bitmap like
Bitmap bmp = Bitmap.createBitmap(mEditText.getDrawingCache());
Now you can add created image bmp to your original image like this
call :
Bitmap combined = combineImages(bgBitmap,bmp);
public Bitmap combineImages(Bitmap background, Bitmap foreground) {
int width = 0, height = 0;
Bitmap cs;
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
background = Bitmap.createScaledBitmap(background, width, height, true);
comboImage.drawBitmap(background, 0, 0, null);
comboImage.drawBitmap(foreground, matrix, null);
return cs;
}
Use canvas (Custom Views) for it..
I think this is the only way to make one view (Image in one canvas) on other view (caption in other canvas) on it. So in this you have to complete knowledge of how views draw on canvas and how to move to that views. And using canvas you can also smoothly move your views on screen.
After creating custom views you can save those views in Bitmap, now you can also combine those images to one bitmap..
(Here Customeviews are ImageViews, TextViews, EditText etc..)
All the best. :-)
USe like this.
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
background = Bitmap.createScaledBitmap(background, width, height, true);
comboImage.drawBitmap(background, 0, 0, null);
comboImage.drawText("title", x, y, paint);