This question already has answers here:
Android scaling of images to screen density
(3 answers)
Closed 7 months ago.
actually I'm trying to create simple app with wallpapers.
I'm trying to scale my image to user device screen size.
I'm using code like bellow:
/*
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
*/
Display metrics = getWindowManager().getDefaultDisplay();
int height = metrics.getHeight();
int width = metrics.getWidth();
float fourToThree;
int wymiar;
Bitmap mbitmap; //definicja zmiennej przechowującej bitmapę
try {
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), cardBase.cardImages[position]);
//UP - zapisanie obrazu z tablicy do zmiennej bitmapy
/*if(height>=width) {
fourToThree = height * 0.75f; //height
wymiar = (int)Math.round(fourToThree);
mbitmap = Bitmap.createScaledBitmap(myBitmap, height, wymiar, true);
} else {
fourToThree = height * 0.75f;
wymiar = (int)Math.round(fourToThree);
mbitmap = Bitmap.createScaledBitmap(myBitmap, width, wymiar, true);
}*/
mbitmap = Bitmap.createScaledBitmap(myBitmap, width, height, true);
myWallpaper.setBitmap(mbitmap);
Toast.makeText(SelectedCard.this, "Wallpaper changed", Toast.LENGTH_LONG).show();
}
catch (IOException e) {
e.printStackTrace();
Toast.makeText(SelectedCard.this, "Sorry, an error occurred", Toast.LENGTH_LONG).show();
}
I was trying many other ways but still have my image larger then device screen :(
I'm testing it on virtual phone and I was trying to create image dit 160 dpi as a device screen, it's not working too.
Can anyone tell me, how can I scale my image (jpg - 320 x 480 px, 300 dpi) to set it as a wallpaper on device ?
Any ideas ?
thanks :)
Ps. sorry for text mistakes, English is my second language ;p
Ok, i have something like that:
imgView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
WallpaperManager myWallpaper = WallpaperManager.getInstance(getApplicationContext());
try
/*{
myWallpaper.setResource(HdImageBase.HdImages[position]);
Toast.makeText(ImageMini.this, "Wallpaper changed", Toast.LENGTH_LONG).show();
}*/
{
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
float fourToThree;
int wymiar;
Bitmap mbitmap; //definicja zmiennej przechowującej bitmapę
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), cardBase.cardImages[position]);
mbitmap = Bitmap.createScaledBitmap(myBitmap, width, height, true);
myWallpaper.setBitmap(mbitmap);
Toast.makeText(SelectedCard.this, "Wallpaper changed \n" + width + "\n" + height, Toast.LENGTH_LONG).show();
}
catch (IOException e) {
e.printStackTrace();
Toast.makeText(SelectedCard.this, "Sorry, an error occurred", Toast.LENGTH_LONG).show();
}
}
});
Width and height values are correct 320 x 480 but image which I'm setting as a wallpaper is still more bigger then my device scren.
After test on my real phone LG L5 with new android (not sure which version). Image is set as wallpaper correct (in portrait mode - 1 image for all 5 "roll screens" without scaling).
How can i tested it on other devices ?
Mean... is this portrait mode for wallpapers is available only in new android version ?
Try this may work :
ImageView property :android:scaleType=“fitXY”
There are 2 ways to scale bitmap to fit a screen:
1st:
the follow function draws the specified bitmap, scaling/translating automatically to fill the destination rectangle:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect src, dst;
int widthOfBitmapSrc, heightOfBitmapSrc;
widthOfBitmapSrc = mBitmapSrc.getWidth();
heightOfBitmapSrc = mBitmapSrc.getHeight();
src = new Rect(0, 0, widthOfBitmapSrc, heightOfBitmapSrc);//size of bitmap
dst = new Rect(0,0,this.getWidth(),this.getHeight());//size of this view
canvas.drawBitmap(mBitmapSrc, src, dst, null);//scale bitmap from src to dst
}
see this link:http://developer.android.com/reference/android/graphics/Canvas.html
2nd:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int widthOfNewBitmap, heightOfNewBitmap;
widthOfNewBitmap = this.getWidth();//width of this view
heightOfNewBitmap = this.getHeight();//height of this view
Bitmap newBitmap = Bitmap.createScaledBitmap(mBitmapSrc, widthOfNewBitmap,heightOfNewBitmap,true);
canvas.drawBitmap(mBitmapSrc, 0, 0, null);//copy bitmap to canvas of this view without scale
}
Related
The code I am using to set a background to a bitmap is
wallpaperManager.setBitmap(result, null, true, WallpaperManager.FLAG_SYSTEM);
wallpaperManager2.setBitmap(result, null, true, WallpaperManager.FLAG_LOCK);
However, the image is not centered and I believe it has to do with the null parameter, which accepts a Rect as visibleCropHint.
How would I set the result bitmap to be centered by X and Y?
As doc says:
Passing null for this parameter means that the full image should be
displayed if possible given the image's and device's aspect ratios,
etc.
So can't guarantee image displayed fully.
Try this(from here):
Bitmap img = BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.paper));
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Bitmap bitmap = Bitmap.createScaledBitmap(img, width, height, true);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(MainActivity.this);
try {
wallpaperManager.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
I am working on recording my screen with MediaProjection
as follows
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
displayWidth = size.x;
displayHeight = size.y;
imageReader = ImageReader.newInstance(displayWidth, displayHeight, ImageFormat.JPEG, 5);
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
DisplayMetrics metrics = getResources().getDisplayMetrics();
int density = metrics.densityDpi;
mediaProjection.createVirtualDisplay("test", displayWidth, displayHeight, density, flags,
imageReader.getSurface(), null, projectionHandler);
Image image = imageReader.acquireLatestImage();
byte[] data = getDataFromImage(image);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Problem is that captured images contains black frame like image below.
EDIT
The above issue can be solved with bitmap operations.
However, I am now looking for a solution that can be applied to MediaProjection or to SurfaceView of ImageReader to implement device recording.
I had a similar issue. The following code exhibits this problem.
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
final int width = metrics.widthPixels;
final int height = metrics.heightPixels;
final int densityDpi = metrics.densityDpi;
final int MAX_IMAGES = 10;
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, MAX_IMAGES);
mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCaptureTest",
width, height, densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
Replacing this:
getWindowManager().getDefaultDisplay().getMetrics(metrics);
With this:
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
Fixes it. The problem is that the decorations around the image corrupt the actual resolution of the screen. getMetrics() returns a height (or width in landscape) that is not accurte, and has the home, back, etc, buttons subtracted. The actual display area available for developers is (1440 x 2326... or something like that). But of course, the captured image is going to be the full 1440 X 2560 screen resolution.
If you do not have control over the image yourself, you can modify it by doing something like, assuming your Bitmap is called image.
Bitmap imageWithBG = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig()); // Create another image the same size
imageWithBG.eraseColor(Color.BLACK); // set its background to white, or whatever color you want
Canvas canvas = new Canvas(imageWithBG); // create a canvas to draw on the new image
canvas.drawBitmap(image, 0f, 0f, null); // draw old image on the background
image.recycle();
Based on your comments I think this is what you are looking for
Bitmap bitmap; //field
Bitmap croppedBitmap; // field
Image image;// field
Handler mHandler; //field
new Thread() {
#Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
imageAvailableListener = new ImageReader.OnImageAvailableListener {
#Override
public void onImageAvailable(ImageReader reader) {
try {
image = reader.acquireLatestImage();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Rect rect = image.getCropRect();
croppedBitmap = Bitmap.createBitmap(bitmap,rect.left,rect.top,rect.width(),rect.height());
\\Do whatever here...
image.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bitmap!=null) {
bitmap.recycle();
}
if (croppedBitmap!=null) {
bitmap.recycle();
}
if (image!=null) {
image.close();
}
}
}
}
imageReader.setOnImageAvailableListener(imageAvailableListener, mHandler);
I have a bitmap downloaded from internet and now i want to decrease the height and width of bitmap without losing the quality of bitmap. How to achieve this.
This is way for downloading bitmap from internet.
URL url_1 = null;
try {
url_1 = new URL(vmImageUrl);
bmp = BitmapFactory.decodeStream(url_1.openConnection().getInputStream());
} catch (Exception e) {
Log.v("Error while downloading bitmap from url", e.getMessage());
I have scaled like this.
Bitmap.createScaledBitmap(bmp, convertDpToPixel(140, context), convertDpToPixel(35, context), false);
This method convets dp unit to equivalent device specific value in pixels.
public static int convertDpToPixel(float dp,Context context)
{
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
int px = (int) (dp * (metrics.densityDpi/160f));
return px;
}
Use BitmapFactory.Options.inSampleSize to get a smaller bitmap.
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(YOUR_FILE, opts);
I set this.
Bitmap.createScaledBitmap(bmp, convertDpToPixel(140, context), VirtualMirrorActivity.convertDpToPixel(35, context), true);
instead of
Bitmap.createScaledBitmap(bmp, convertDpToPixel(140, context), VirtualMirrorActivity.convertDpToPixel(35, context), false);
Its give smoother edges & clear of bitmap. Now its working fine..
you need 2 Rect,
Rect src = new Rect();
Rect dst = new Rect();
then u can set the src for the current image,
src.set(0,0,imgWidth,imgHeigth);
then then the required size
dst.set(startX,startY,endX,endY);
Note: startX and startY will be the destination coordinates on the screen
and ur image will be drawn u to the endX endY coordinate.
and draw ur bit man with Canvas
Canvas.drawBitmap(bitmapFile, src, dst, null);
I'm trying to set a .PNG file as background on Canvas in my app. I've made an image 480 x 800 and used this method:
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.image_1), 0, 0, null);
I've started an emulator (WVGA800) but my image looks greater than screen of the device.
How do I resize this image or what kind of methods should I use to make this image well-matched.
Secondly, is there any way to make backgrounds like this universal for devices with different screen resolutions?
Thank you in advance.
Try this one ...
Set bitmap
Bitmap mFinalbitmap= BitmapFactory.decodeResource(getResources(), R.drawable.image_1);
Resize bitmap as per your width and height
mFinalbitmap= resizeImage(mFinalbitmap, width ,height);
Set Canvas of Bitmap
canvas.drawBitmap(mFinalbitmap, 0, 0, null);
Resize Function: As per maintain x and y of image
public Bitmap resizeImage(Bitmap image,int maxWidth, int maxHeight)
{
Bitmap resizedImage = null;
try {
int imageHeight = image.getHeight();
if (imageHeight > maxHeight)
imageHeight = maxHeight;
int imageWidth = (imageHeight * image.getWidth())
/ image.getHeight();
if (imageWidth > maxWidth) {
imageWidth = maxWidth;
imageHeight = (imageWidth * image.getHeight())
/ image.getWidth();
}
if (imageHeight > maxHeight)
imageHeight = maxHeight;
if (imageWidth > maxWidth)
imageWidth = maxWidth;
resizedImage = Bitmap.createScaledBitmap(image, imageWidth,
imageHeight, true);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}catch(NullPointerException e)
{
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
return resizedImage;
}
where did you put the image? if it's in the drawable or the drawable-mdpi , it will be larger than what you've told , since WVGA800 has a high density (hdpi) .
even if you put it on the drawable-hdpi folder , it will work for WVGA800 , but it might not show well on other devices , which have different resolutions and aspect ratio .
you need to handle the scaling and keeping of aspect ratio (if you wish) . otherwise , you will have the same problems on other devices.
The easiest way:
declare static Bitmap in your class:
Bitmap bitmap;
setup the resized bitmap, for example you want resized bitmap to 100x100:
private void initBitmap(){
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.Your_bitmap);
bitmap = Bitmap.createScaledBitmap(bitmap, 100,100,true);
}
and call method in constructor
I am working on a simple wallpaper app of some images that I have. They are .png files in drawable folders.
Here are some code snippets:
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
....
myWallpaperManager.setResource(R.drawable.image1);
No matter what size or resolution I seem to use, when the wallpaper is set it crops the original image. When I use the same image as a background it is the correct size and shows the entire image. I thought it might be a problem with my emulator so I have tried running it on an actual device (HTC eris) and I am having the same problem. I have made the image the screen size and resolution for the eris and it is still cropping it. I then made the image only one inch high and a resolution of 100 dpi. It was very pixelated on the eris, but still cropped the image.
Any help would be greatly appreciated.
I attempted to add some images to show the before and after, but as a newer user I was prevented from doing so.
Check the values returned by http://developer.android.com/reference/android/app/WallpaperManager.html#getDesiredMinimumWidth() and http://developer.android.com/reference/android/app/WallpaperManager.html#getDesiredMinimumHeight() and try to use these values as the dimensions of your wallpaper.
Maybe I can help.
// 1. Get screen size.
DisplayMetrics metrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);
final int screenWidth = metrics.widthPixels;
final int screenHeight = metrics.heightPixels;
// 2. Make the wallpaperManager fit the screen size.
final WallpaperManager wallpaperManager = WallpaperManager.getInstance(ViewWallpaperActivity.this);
wallpaperManager.suggestDesiredDimensions(screenWidth, screenHeight);
// 3. Get the desired size.
final int width = wallpaperManager.getDesiredMinimumWidth();
final int height = wallpaperManager.getDesiredMinimumHeight();
// 4. Scale the wallpaper.
Bitmap bitmap = getBitmap(); // getBitmap(): Get the image to be set as wallpaper.
Bitmap wallpaper = Bitmap.createScaledBitmap(bitmap, width, height, true);
// 5. Set the image as wallpaper.
try {
wallpaperManager.setBitmap(wallpaper);
} catch (IOException e) {
e.printStackTrace();
}
Note that you should call suggestDesiredDimensions, then call getDesiredMinimumWidth and getDesiredMinimumHeight to get the size to be scaled to.
I had the same problem. I made an image that is the size of the screen and adding padding to the image so that it is as large as the WallpaperManager getDesiredMinimumWidth() and getDesiredMinimumHeight().
It seemed better to have some code automatically add the padding so that is what I used below. Make sure the image is the same size as the screen.
private void setWallpaper() {
try {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
//import non-scaled bitmap wallpaper
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap wallpaper = BitmapFactory.decodeResource(getResources(), R.drawable.wallpaper, options);
if (wallpaperManager.getDesiredMinimumWidth() > wallpaper.getWidth() &&
wallpaperManager.getDesiredMinimumHeight() > wallpaper.getHeight()) {
//add padding to wallpaper so background image scales correctly
int xPadding = Math.max(0, wallpaperManager.getDesiredMinimumWidth() - wallpaper.getWidth()) / 2;
int yPadding = Math.max(0, wallpaperManager.getDesiredMinimumHeight() - wallpaper.getHeight()) / 2;
Bitmap paddedWallpaper = Bitmap.createBitmap(wallpaperManager.getDesiredMinimumWidth(), wallpaperManager.getDesiredMinimumHeight(), Bitmap.Config.ARGB_8888);
int[] pixels = new int[wallpaper.getWidth() * wallpaper.getHeight()];
wallpaper.getPixels(pixels, 0, wallpaper.getWidth(), 0, 0, wallpaper.getWidth(), wallpaper.getHeight());
paddedWallpaper.setPixels(pixels, 0, wallpaper.getWidth(), xPadding, yPadding, wallpaper.getWidth(), wallpaper.getHeight());
wallpaperManager.setBitmap(paddedWallpaper);
} else {
wallpaperManager.setBitmap(wallpaper);
}
} catch (IOException e) {
Log.e(TAG,"failed to set wallpaper");
}
}