Android - dealing with images/camera - couple questions - android

I'm dealing with resizing of images on Android - fun! Here is questions I have hopefully small :)
I'm using camera intent to take picture and save it on SD card.
Is there any way to get camera resolution so I will know resolution of image and don't need to check it every time when convert?
Is resolution something that may change or it is fixed per device?
Are all images saved in "landscape" format? I mean they always "wider" than "taller"?
If I have ImageView on a screen - how do I know what size Bitmap it needs to fill properly? I have 4 Imageviews in a row - all with equal weight so I guess I need to come up with screen width and resize Bitmap appropriately?
If I need to scale image to exact width - does it mean I have to calculate "ratio" from OldX to NewX and than apply it to OldY before calling Bitmap.createScaledBitmap?

You're looking for the getSupportedPictureSizes() method: http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPictureSizes(). And there's plenty of sample code out there once you have method names to search for.
Answered by 1.
You can either use the orientation or ignore it, see setRotation at http://developer.android.com/reference/android/hardware/Camera.Parameters.html
You can just call getWidth() and getHeight() on the image views and resize the bitmaps to fit.
Or you can set the scaleType for the image view itself to CENTER_INSIDE and just add the bitmap to it, assuming you already have a bitmap. http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

Related

Camera2 preview stretched when cropping with SCALER_CROP_REGION

I want to display a preview in fullscreen using camera2 api. The camera size I selected is 4160x3120 (16:9) and my screen is 1080x1920 (9:16). Therefore if I want the preview to be right scaled I have to crop the camera output :
Rect zoomCrop = new Rect(0, 0, 1755, 3120);
captureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomCrop);
The cropped preview should be of size 1755x3120 which has a ratio of 9:16 as well. Still the preview is streched.
Question :
Am I using SCALER_CROP_REGION correctly ? If not, how am I supposed to use it ?
Thanks in advance
I've been struggling with the same sort of problem, as I want to implement a camera preview stream into a square TextureView.
Working with the SCALER_CROP_REGION seemed like the obvious place to resolve issues with incompatible aspect ratios, but I don't think that operation will ever actually change the aspect ratio of the result, hence it doesn't prevent stretching/warping behaviour. (the docs talk about this)
I've made progress by implementing a similar transform to the one in the Camera2Basic example project - see the function configureTransform in Camera2BasicFragment).
Using this sort of view-level scaling matrix, you can manage the scaling/cropping of the camera preview without altering the size of your view.
It sounds like you are getting a landscape image and displaying it in a portrait view - this means that you will have 'pillar box' lines above and below the image if you want to avoid distortion.
If you did want to fill the screen, and not have distortion or the pillar box lines then you would have to accept that part of your image will not be visible, as its outside the shape of the viewing area.
SCALER_CROP_REGION is tricky to understand without diagrams - I found the best explanation to be in the Andoir source documentation here: https://source.android.com/devices/camera/camera3_crop_reprocess
One diagram reproduced from that helps as an example here - the reason for highlight this is to show how the co-ordinates are being used. If you look at your crop region it will be biased towards the top left as you start at (0,0), which I am not sure is what you actually want.

How to keep canvas position of saved image no matter the device resolution in Android?

I am saving three imageviews to one bitmap after the user edits the image(s). The problem is that once the final result is saved, the resulting saved image doesn't always look the same on different screen resolutions.
On my phone, which is a Asus Padfone X, the saved image comes out perfectly. On my partners phone, Note 6, the positioning of the saved images on the resulting bitmap are off. (See example below)
I am using the following code to save the imageviews to a single image:
Bitmap mainBmp = backImage.getDrawingCache();
Bitmap centerBmp = centerImage.getDrawingCache();
Bitmap handleBmp = handleImage.getDrawingCache();
Canvas canvas = new Canvas(mainBmp);
canvas.drawBitmap(centerBmp, 17, 95, null);
canvas.drawBitmap(handleBmp, 17, 85, null);
Which saves properly on my phone but not one with a bigger screen/higher resolution. How do I ensure the resulting saved image looks the same regardless of the device it is saved on?
EXAMPLE OF DIFFERENCE
You need to scale. For example, lets say that device 1 is 500x1000 pixels and device 2 is 600x1200. Lets say the bitmap is 300x400 and starts at an offset of 30 pixels in x and 100 in y.
The bitmap needs to grow in size by the ratio of the two screens sizes. So it would need to be 300*(600/500) pixels wide and 400*(1200/1000) pixels big. The offset would need to scale as well- to 30*(600/500) and 100*(1200/1000).
Please note that when scaling you may get stretching, pixelation, and other image defects. The more you stretch the worse it will be. Shrinking can also give defects, but these tend to be more minor.
This is the simple case- the two screens I gave have the same aspect ratio (ratio of width:height). In the case of different aspect ratios, you need to choose:
1)Keep the aspect ratio of the image the same. This will mean you'll have blank space in 1 direction, but the image won't be effected.
2)Allow the aspect ratio of the image to change. This will leave no blank space, but will skew the image.
For #2, use the same code as above. For #1, figure out which dimension needs to scale the least, and use that to scale x and y.
It is not possible to scale from any size phone to any size phone without any defects on a generic image. You'll have to choose between the two options above.
I also found that if I instead use imageview.getWidth() and imageview.getHeight(), I can position each "layer" where I need it to be no matter the screen size. I tested this method on a small android device all the way up to a tablet and the saved image came out perfect across all devices.
What I did was determine the pixel size of each image("layer") using Photoshop. I then used an online px to dp calculator/converter to determine the correct dp size of each layer. I set specific dp width and height for each layer in the layout. For each layer I needed to save to the main image, I calculated the x and y dimensions by taking the mainimageviews height and width and subtracting the pixels needed from the edge to the respective edge of that layer. Through trial and error, I ran the app a few times to get the exact positioning of each layer I wanted. The result of the saved image was exactly the way it looked to the user. Hope this helps someone else in the future.

ImageView bitmap is stretched after activity transition

Is there any specific reason why this is happening?
This is the image after the transition happens.
You haven't provided any code to help us diagnose your problem, but your terrifying image (that looks like Jim Carrey) may be related to the tileMode. Your image looks like it's exhibiting clamping.
Clamping is when the edge color is replicated if the bitmap for an ImageView is smaller in size than the ImageView. These are all the options, along with a suitable picture of Jim:
disabled - Do not tile the bitmap. This is the default value.
clamp - Replicates the edge color.
repeat - Repeats the bitmap in both direction.
mirror - Repeats the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam.
Since it looks like your Bitmap is smaller than your ImageView and I don't think you actually want to use any tile mode (just use the default of disabled), I'd recommend either:
A) Use ImageView's setScaleType() so that the Bitmap resizes to fill the ImageView, using the centerCrop value (though check this blog for more examples), or...
B) Make your Bitmap larger
(I'd recommend A)

how to scale images appropriately to fit the screen

In my app I have a Gallery-similar functionality and faced the issue that I need to scale the images. My test device in Nexus 5 which has a screen width of 1080p (360dp). Below are screenshots of an image having a width of 604 pixels opened with my app and the system-default Gallery:
My app:
=============================
Gallery:
The code I use to show the image is quite simple:
pathToImage = getIntent().getStringExtra("path");
img = (ImageView) findViewById(R.id.imgPictureView);
try {
bmpImage = BitmapFactory.decodeFile(pathToImage);
img.setImageBitmap(bmpImage);
} catch (Exception e) {
e.printStackTrace();
}
Opening a hi-res camera photo causes my ImageView to adjust its width to fill the screen, however I'm getting a heap size of about 80 (!!) MB.
It's obvious that the system gallery decides whether to scale the Bitmap up/down to make it fit the screen. For example, it scales a 60px image up, but only by a small factor so it doesn't become really blurry. I guess it also scales large camera pictures down to prevent OutOfMemoryError's. So in my example above, the gallery assumed the width of 604px is enough to scale it up to 1080 without noticeable quality loss, my app of course not due to lack of any additional code.
So the question is: how can I achieve the same result and determine the factor to scale images up/down without quality loss depending on the current screen?
Note: for those who will now post tons of (beyond controversy amazing) code examples showing how to actually scale a Bitmap or determine the screen width - this is NOT my question.
Bitmap can use a lot of memory and you got to scale them down. Instead of giving you a copied solution, here's a detailed documentation:
http://developer.android.com/training/displaying-bitmaps/index.html
You really should go through the whole guide. There's a lot to learn.
Second, set your ImageView's width to MATCH_PARENT and try changing its scaleType attribute to centerCrop. Play with the other available values for scaleType to get your desired result.

Displaying images from the web?

How to display an image using a URL of a known jpg, png ..etc. File ?
I want an image , and I want it to be loaded from the internet from a particular website.
With that done,
I would like to make that image of an appropriate size...
Say I put the width as the same as screen_width (size)....What about the height ? I don't want to spoil the ratio of height/width of the original image...So is the height automatically set to account for the ratio ? or do I have to put in some value myself ...?
Plus, I want it to be zoomable.
To load images from website, you need to get the path from website server where the photo is stored. For image displaying put height as wrap_content mode so that the space will occupy as much as needed to display.
For this purpose you can use a Lazy Adapter. Here you can find a good example of it: https://stackoverflow.com/a/3068012/2436683. Maybe you can use it as a starting point.

Categories

Resources