I have a background png in my Android application. I would like to support lots of displays, but I have this one obstacle - many displays have many resolutions and many ratios. I would like to make sure my background is displayed properly and make it more ellegant, than just creating 10+ cropped png files in Photoshop.
My idea would be - a fairly large picture imported in the project. The app would find out screen dimensions and simply say starting points(x,y) and ending points, that would "crop" the picture and display it without any deformations.
Is there a way of doing it?
I think bitmap.createBitmap() is the method your looking after. The method simply lets you cut out a defined portion of the bitmap.
Related
I'm new to Android development. I have a library here that produces LCD images that come from a device through USB. These images are small, 120x80 pixel, and are 1-bit. I want to show these images on the UI.
All documents I've found explain how to show bitmaps from image files (PNG etc.) or how to show them from an app's resources. I did find out that I can add an ImageView to the UI. Then, for each incoming 120x80 pixel image, create a Bitmap instance, fill it with pixels, and assign it to the ImageView. However, I do not know if this yields the best performance here.
It is also important to keep in mind that nearest neighbor scaling must be used here. Bilinear filtering with such a small image produces a result that is too blurry.
From my experience with other languages, it seems wasteful to create a Bitmap instance for each incoming image. But perhaps I am wrong here.
Suggestions?
I'm having trouble cleanly down-scaling images on Android. I'm looking to scale small PNG images between arbitrary sizes of about 10-100% of their original size.
I've created a sample image to demonstrate the problem and exacerbate the unusual behaviors I'm seeing in Android's image scaler:
The above image is a screenshot from an Android device with some annotations added. I've also added the same images in a second column on the left side showing how they are rendered with a linear scaling by "The GIMP" (GNU Image Manipulation Program).
The base image consists of a checkerboard pattern background of red and blue pixels. On that background I've drawn some 1px-wide yellow lines and fairly thin green text. The image is 288x288 pixels.
When scaling the image to 1/3 of its original dimensions, Android seems to simply grab one in nine pixels, throwing out all other data. Some of the yellow lines disappear entirely as a result. Remarkably, the checkerboard pattern remains intact (which is simply a result of every 3rd pixel being used).
When scaling the image to a dimension of near-but-not-exactly 50% of its original size, e.g., 142x142 or 143x143, the scaler creates some fairly large anomalies/artifacts on the image.
At 50% size (144x144), the image looks correct.
The test image does bring out the worst of the image scaler, but "normal" PNG icon images are severely impacted as well. From 10-33% or so the images aren't properly resampled, and thus appear extremely "bitmapped". And certain larger size images have very strange anomalies in them at certain sizes.
If anyone knows a means to disable this strange scaling behavior, even at a performance cost, I'd greatly appreciate knowing about it. It can certainly be solved by writing an algorithm that works directly on the pixels of bitmaps, but I'm hopeful that isn't the only option.
Also noteworthy is the fact that all image work is being done with ARGB_8888 Bitmap.Configs. I've tried manipulating image size by setting maxwidth/maxheight on ImageViews, by using Bitmap.createScaledBitmap(), and by using Bitmap.createBitmap with a Matrix. All attempts have this same result. Bitmap filtering is enabled.
Thanks again for any suggestions!
Using Bitmap.createScaledBitmap() and Bitmap.createBitmap with a Matrix is the same; see the source for Bitmap.createScaledBitmap (which hasn't changed since Android 2).
On Android 4.0+, using a matrix (as in Bitmap.createScaledBitmap) allows hardware-accelerated operations if enabled (enabled by default on 4.1+ IIRC), thus we doesn't have direct control over what is being done and how it is done.
That means you'll have to implement your own scaling method using the desired (here, linear) filtering; either by pixel processing; or using OpenGL ES with the good filter, but it may not be available on all devices.
i was wondering if is it efficient and possible to set 3000X2000px image as canvas background without resizing it and without getting the memory error.
because i want the real size image and pan around it.
using webview is not an option.
Currenty i tried to the set the background by using a folder structure named "Drawable-nodpi" and then assinging the bitmap image with decoderesource method.
Such a huge picture will inevitably cause outofmem exceptions on at least some devices. So I think that you need to dynamically scale and load only parts of the image that needs to be displayed, possibly with a caching mechanism.
Unfortunately, I don't know about any library components for Android that does this for you out of the box, but I'm pretty sure that you can find some nice articles on this topic.
I have two situations/projects where I have to use a large bitmap as background activity.
The first project ports a WP7 application to Android! The WP7 app is using a panorama control with a bitmap as large as 3 screens. I would like to reuse the large bitmap similar in a way that I use the left part for the first activity, the middle part for the second activity and the right part for the third activity. In other words I would like to define which part to crop.
In the second project we try to develop an app which should run on various screen sizes (including tablet), the app should also use a background image. Is it a good idea to provide only one picture with a quadratic size (as long as the largest screen width) and use this picture through every resolution and just crop the background image depending on the actual size of the display?
Is it possible to crop pictures on Android?
Is it possible to define the part of the picture which is kept?
Is it possible to use this croped pictures as background image or may I encounter performance penalties?
What do you think of this technique? Is it a good idea?
Thanks for your help!
answering your questions:
yes it is possible to crop pictures in Android (I've done so)
you can define wich part of the picture is shown in each activity
with a canvas and only drawing the rect that corresponds to the part
of the image that you want to display (eventough I wouldnt suggest
the approach of having diferent activities with the "same" content)
yes, you can use cropped pictures as background image for whatever
you want. Once you cropped the image use that bitmap and save it in
the device and then you might use it as you wish, and eventought is not recommended to have the whole image as background you can do so.
I suggest that you use a SurfaceView since you will be able to move it (the image) all around the screen without having to create a new activity. Here is a good tutorial to SurfaceView Playing with graphics in Android – Part I and this approach will also work with Tablets.
I have a graphic designer that helps me with UI development. We start with me taking screenshots of my current UI using my Nexus One (800x485). Then he overlays new art over the old screenshots in Photoshop and creates transparent PNGs. Then I take that, plug it in my app and to my dismay these images appear big and blurry (about 35% larger). When I check images these are created at 72 dpi so I really have no idea why this is happening. Any ideas?
You need to put the graphics in the correct configuration directory for the target screen. If they are being designed for N1, that 800x480 screen is a high density screen, so the graphics need to go in drawable-hdpi. Not in the generic drawable directory, which for backwards compatibility is assumed to be mdpi.
I edited my answer since it was not the correct one.
Other idea, how are you handling your draws ?
(if your using a custom view draw you could post the code if this doesn't help).
I'm asking because there is a trap while drawing with the dimensions:
are you using
bitmap.getScaledWidth
instead of
bitmap.getWidth
that could lead to imprecise/bigger images.
The current idea I have in mind is: (easier to explain with an example):
you have an image of 100*100
you display
you capture it
you edit it and make it pretty
you reinject it
you display it but because your on a high res the dp scales it and it gives it a bad aspect
I don't know if I'm being very clear. but if your using a custom view for your display then you should check your scales.