I tried following some ImageView and BitmapDrawable source code to gain a better understanding of how the two classes operate on BitMaps. Is this generically how the process works?
I have an image which is a JPEG of size 500x500
I have ImageView A which is size 250x250, and ImageView B which is size 500x500.
Both have a BitmapDrawable which contains the JPEG
When its time to draw the Bitmap, A and B will both apply a matrix that will scale the bitmap appropriately to their respective canvas.
The JPEG itself will remain unscaled
Related
Why does drawing a shape to a bitmap cause the shape to be blurry versus drawing the shape straight to the canvas?
Bitmap is a rasterized computer image, consisting of points (pixels).
The Canvas class holds the "draw" calls.
A shape is an abstract definition of shape (vector-like).
drawing the shape straight to the canvas
That's not accurate, maybe you mean straight to the screen of device, which is Bitmap too.
To use Canvas for drawing, you need the canvas to host the calls, some bitmap as target, and some drawing primitive (shape is one), and Paint (contains information how to paint the drawing primitive).
Once you draw some shape into the target bitmap, it will be aliased to the pixels of target bitmap. Ie. an circle will turn into some approximation created by rectangular pixels of target bitmap.
What you probably see in your particular case is, that your Bitmap has lower resolution than screen, and when you draw that low-res bitmap to the target screen bitmap, it is upscaled by some filter which makes the upscaled picture a bit blurry to avoid big rectangular pixelation (or it may be also other way, downscaling hi-res bitmap, which contains too sharp/thin contours, which will be aliased second time when downscaled, and even with anti-aliasing filtering it will get blurred a bit). Or maybe you use some paint with settings causing blur (unlikely, can't think of creating one by accident, you would knew).
If you will use for both targets Bitmap of identical density (resolution of single pixel), and the same paint method, then the result will be same, and also drawing the shape from bitmap to bitmap as long as you will use whole pixel coordinates/size, and no filtering, again the result will be same as drawing directly to screen bitmap.
So start first by checking the size of your bitmap vs screen bitmap, and then check paint settings and additional canvas arguments to draw the bitmap, whether you don't upscale/downscale it with some kind of filtering.
I have an image which is monochrome, meaning only white and black pixels. I have made several versions of the image in order to cover all dpi folders. I am using a monochrome image since I want to apply the floodfill algorithm.
The problem is that in some devices, android uses resized versions of the images and while scaling there are some grey pixels. In order to deal with this I tried correcting the pixels and converting the grey to either white or black, but this takes significant time.
Is it possible to force android to generate monochrome images while resizing the imageview or to apply a quick filter to regenerate the monochrome image?
While I haven't tried it, should I generate different versions of the images in the nodpi folder and use them without scaling, perhaps with center crop?
You can load the Drawable as Bitmap.
final BitmapFactory.Options options = new BitmapFactory.Options();
// Load the bitmap as mutable object
options.inMutable = true;
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_image, options);
Then you can manipulate it with your algorithm and finally you will set the result to your ImageView
imageView.setImageBitmap(bitmap);
This way you should not get any grey pixels caused by Android Scaling.
For more options:
See here,
And here.
I am very new to OpenGL ES.
To my understanding openGL ES only allows power of two sized images for textures (eg 512*512 or 256*256 etc...). I am looking for a way to display images of different sizes as textures but they are not power of 2 sized and their size varies.
The pictures will be downloaded from the internet. Resizing them before downloading is out of the question.
Is there a way to use non POT sized images for textures? Do I have to create a method to resize them? Is there a library out there somewhere that does that?
The textures will be applied to rectangles using the library min3d:
http://code.google.com/p/min3d/
thks!
EDIT:
example of texture loading from resources:
InputStream is =getResources().openRawResource(R.drawble.drawable1);
Bitmap bitmap;
bitmap = BitmapFactory.decodeStream(is);
When you load in an image, you could create a larger Bitmap container for it that is of a POT size. Then copy the non-POT image into it. When you load the new Bitmap as a texture you can then crop it to the size you want (third parameter of glTexParameteriv()).
To create the container Bitmap:
// work out the pot size you need from the source Bitmap's size
// ...
Bitmap bigger = Bitmap.createBitmap(potWidth, potHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bigger);
canvas.drawBitmap(nonPOTBmp, 0, 0, null);
// free up memory
nonPOTBmp.recycle();
I am using a Custom ImageView. In its onDraw I do some processing by using the canvas which is like drawing line, bitmaps based on user touch.
To save the resultant snapshot when the user want to save the image, we are using drawingCache
imageView.setDrawingCacheEnabled(true;
Bitmap.createBitmap(imageView.getDrawingCache(), 0, 0,
imageView.getHeight(), imageView.getWidth(),
matrix, true).compress(CompressFormat.JPEG, 95,
new FileOutputStream(file));
Of course I can use this to get the actual image while user presses save but the image does not contain any of the processing done on the imageView.
Bitmap bmp = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
Bitmap.createBitmap(bmp, 0, 0,
bmp.getWidth(), bmp.getHeight(),
matrix, true).compress(CompressFormat.JPEG, 95,
new FileOutputStream(file));
Problem:
The size of the image saved is the size of the imageView which is fullscreen but depends on the device. For smaller screen size phones it goes down to 240 X 320.
Question:
a. Is it possible to get a decent size image irrespective of the device screen size?
b. Is it possible to do Image Processing directly on the Image that is being used in the Custom ImageView?
Thanks in anticipation!
Any thoughts?
Maybe an alternative would be use the Canvas class to do some of your drawing and image display: javadoc: android.graphics.Canvas.
The ImageView class is not the best when images need to "refreshed" often.
If you decide to stick to ImageView, don't create the bitmap using the ImageView's dimensions. Retain the aspect ratio of the image, and compose your bitmap according to the big dimensions you need. The imageView will shrink it (if needed) to fit the screen.
You can use
Bitmap.createScaledBitmap(Bitmap b, int newWidth, int newHieght, boolean filter);
and to get a bitmap from resources use
Bitmap image = BitmapFactory.decodeResource(..)
you can then use
ImageView.setImageBitmap(Bitmap bm)
to set the new bitmap to the imageview
I have a class that extends View. I override the onDraw method and allow the user to draw on the screen. I am at the point where I want to save this view as an image. I Can use buildDrawingCache and getDrawingCache to create a bitmap that I can write to the SD card. However, the image is not good quality at a large size, it has jagged edges. Since I have a View and I use Paths I can transform all by drawing to a bigger size. I just don't know how to make the Canvas bigger so when I call getDrawingCache it doesn't crop all the paths I am just transformed. What is happening is I transform all my paths but when I write the Bitmap to file I am only getting the "viewport" of the actual screen size. I want something much bigger. Any help in the right direction would be greatly appreciated. I have been reading the docs and books and am at a loss.
Thanks
Jon
You can create another Canvas backed by a Bitmap that you create and draw all the paths to that. Then the Bitmap will hold the larger, higher resolution image. It would look something like this:
Bitmap largeBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas largeCanvas = new Canvas(largeBitmap);
// Draw the paths to this canvas and then use largeBitmap to save to a file.