Android bitmap rotate canvas crops/cuts image - android

bmpAndroidMarker = BitmapFactory.decodeResource(context.getResources(), R.drawable.t_move2);
bmpAndroidMarkerResult = Bitmap.createBitmap(bmpAndroidMarker.getWidth(), bmpAndroidMarker.getHeight(), Bitmap.Config.ARGB_8888);
Canvas tempCanvas = new Canvas(bmpAndroidMarkerResult);
tempCanvas.rotate(direction+45, bmpAndroidMarker.getWidth()/2, bmpAndroidMarker.getHeight()/2);
tempCanvas.drawBitmap(bmpAndroidMarker, 0, 0, null);
This it the code I have written (borrowed). The icon is generated within an imageview, inside a listview.
My problem is that on rotating this 'arrow', it seems that it 'clips' part of the far edges off, as if it were keeping the original bitmap's dimensions. I can't figure out how to allow it to 'overflow' and render the correct size image.
Is there some way of doing this?

You're rotating the Image by 45 degrees so the resultant Bitmap should be the width of the original plus the originals diagonal width (Pythagoras' Theorem should be able to help).
AFAIK you'll need to do that Maths yourself when creating the result Bitmap as that's the canvas which is being drawn upon, rotating it's contents will not rotate the container.

Try wrapping your ImageView in a FrameLayout and setting the frame layout's width and height as the size of the image you are trying to render. You can do this in the view's layout file like ...
<FrameLayout
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="YOUR IMAGE WIDTH"
android:layout_height="YOUR IMAGE HEIGHT">
<ImageView
android:scaleType="matrix"
android:layout_width="YOUR IMAGE WIDTH"
android:layout_height="YOUR IMAGE HEIGHT"
android:src="#drawable/YOUR IMAGE FILE" />
</FrameLayout>
... or in a programmatic way by building your FrameLayout with your specified dimensions then adding your ImageView as a subview.
If your image is bigger than the screen you can use android:scaleType="matrix" to keep it from scaling and ensure your aspect ratio is retained.
This was originally answered by Pavlo Viazovskyy here. Credit where credit is due!

Related

Image View doesn't show clear image defined in xml

In my code I want to set a default image for my imageview. All my images are of 174px X 174px. So, I want the default image to be same size. This is my xml for image view
//....code
<ImageView
android:id="#+id/ivCover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="Default Image"
android:src="#drawable/default_cover" />
//....some other code
Now, my default_cover.jpg is also 174px X 174px. But it shows a smaller image. I've tried all
android:scaleType="centerInside"
android:scaleType="center"
android:scaleType="matrix"
even when most of them were senseless for me but still I tried all of 'em & none of them works. Then I specified the height & width of image by specifying
android:layout_width="174px"
android:layout_height="174px"
(I know using dp is better than px but because this image size is fixed & I was just testing it). So it shows
[default image]
while when loaded from an external url using
Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(url_source_for_image).getContent());
ivCover.setImageBitmap(bitmap);
desired image
[]
The two pictures may not look very different here but the difference is very clear on my android device. And please don't say that I didn't try other solutions..
Here is a list of links of so itself..
ImageView fit without stretching the image
Fit image into ImageView, keep aspect ratio and then resize ImageView to image dimensions?
ImageView one dimension to fit free space and second evaluate to keep aspect ration
Resizing ImageView to fit to aspect ratio
Maximum width and height for ImageView in Android
Image in ImageView is stretched - Android
Android: How to prevent image from being scaled in ImageView or ImageButton?
Sounds like the answer is to use drawable-nodpi. For future reference, if you have the same named image in both the ldpi/hdpi/etc and in no-dpi, I think the no-dpi one will be ignored.

imageView.setImageResource(int resId) vs. imageView.setImageBitmap(Bitmap bitmap);

The image file is identical. Once it comes from the drawable and one from the file system.
Here is the code.
<ImageView
android:scaleType="fitEnd"
android:id="#+id/partner_logo"
android:layout_width="51dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="#string/parter_logo"
/>
I would like to set the partner logo dynamically, so I load id from the webserver and then
set with imageView.setImageBitmap(Bitmap bitmap);
with the ImageResource it looks good and as I expect but in Bitmap case it is too small.
Here the picture to compare
The Logo (black arrow points) was set via setBitmap. It seem not to be up-scaled
--
The Logo (read arrow points) was set via setImageResource. It looks as I would like it too look like.
So the question is why there is a difference here? Works the scaleType in case of bitmap?
Because setImageResource() automatically scale your image.
If you want to use setImageBitmap() you need to scale up your bitmap to your desired size or using setAdjustViewBounds(true) that keep your aspect ratio.
Bitmap.createScaledBitmap(yourbitmap, width, height, false);
http://developer.android.com/reference/android/graphics/Bitmap.html

Setting a Bitmap to a ImageView

I have downloaded a Bitmap from a WebService, and set it to an ImageView. The ImageView has a set height of 120dip and a width set to FILL_PARENT, so it fills the complete width of the screen. Now i want to stretch the Bitmap to fit the width of the ImageView, but the if the height of the Bitmap is greater then the height of the ImageView, i want the remainder of the image to flow off the top and bottom of the ImageView. So in way, like i have a frame infront of the image and the only portion of the image visible is the contents of the frame. How can i do this ?
See Android Developers on ImageView ScaleType
You are interested in the scale_type enum. Use CENTER_CROP.
Here is complete example:
<ImageView android:layout_width="fill_parent"
android:layout_height="120dp"
android:layout_gravity="center"
android:src="#drawable/eureka"
android:scaleType="centerCrop">
</ImageView>
Here is also a cool visualization of all possible options for ImageView.

Remove ImageView auto-resizing

I want to put and ImageView with a large Y margin on my screen device, which would imply that part of the image would be out of screen, and then that the image would be cropped.
The problem is that Android is scaling the image all the time, so that it fits inside the screen, but I don't want that, I want the image to be cropped.
How can I force the ImageView to be cropped and not resized?
P.S. I tried all the possible ScaleType properties and none of them worked for me!
Code :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:background="#drawable/my_image"
android:scaleType="centerCrop"
/>
</RelativeLayout>
Try replacing android:background with android:src.
First problem with your code is that you used:
android:background="#drawable/my_image"
instead of:
android:src="#drawable/my_image"
(with background none of the scaleType options work).
Now if this still doesn't help, you probably have to use scaleType="matrix" and then simply create a matrix that will do the required job. For example, let's assume that you want to:
keep the ratio of your image
scale the image so that the width parameter will equal X (for example: X can be the width of the screen)
make the top of the image visible (so crop the bottom of the image) - I'm assuming this is why centerCrop might not work for you
Here's the code:
ImageView imgView = (ImageView)findViewById(R.id.my_image_view);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.my_image);
Matrix matrix = new Matrix();
// Let's assume X = 400
float scale = ((float) 400) / bitmap.getWidth();
matrix.setScale(scale, scale);
imgView.setImageMatrix(matrix);
And remember to make the necessary changes in the xml file.

Scale images in android relative to screen width

I have a layout with two images:
one that should strech to the screen width
one above it that should scale to the same proportion the first one was automaticaly scaled (relative to the original image size)
More specific: the two images are slices of the same image, and therefore some details inside them should match.
Can I make this in XML?
If I cannot do it through XML, maybe I could prescale the graphics. In this case, how should I prescale them?
This is a bit of a hack, but it would allow you to do this in xml.
If you know that, for example, the top image is X% of the size of the bottom one, then you can use LinearLayout's layout_weight to position and size the top image in terms of percentage of the screen:
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView android:id="#+id/left_filler" android:layout_weight="20"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<ImageView android:id="#+id/top_image" android:layout_weight="50"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<ImageView android:id="#+id/right_filler" android:layout_weight="30"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
... bottom image
The above would size top_image at 50% of the screen with an offset of 20% from the left. As long as top_image is 50% the size of bottom_image, this will keep similar scale.
Alternatively, the "right" way to do this is probably to override onDraw() in a custom view and use canvas drawing methods.
You could use the Canvas class method drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
for drawing the specified bitmap by scaling/translating automatically to fill the destination rectangle. This can be used for both the bitmaps with different Rect. The Rect can be formulated by dividing the current width and height of the layout. So that the program will scale the images in accordance with devices having different screen size.

Categories

Resources