Using an ImageView, I can set a square height and width (say 100dip x 100dip). Then using android:scaleType="centerCrop" gives me an image which is cropped to square regardless of aspect ratio.
Can we do this with a VideoView?
I've tried just setting a square height and width, but it just re-sizes to fill the square as best as it can while maintaining the aspect ratio, which I guess is completely expected.
It doesn't seem to have any scale or crop properties / methods unlike ImageView, but this in the VideoView documentation makes me think I'm missing something:
[VideoView] ...provides various display options
such as scaling and tinting.
Any ideas would be much appreciated.
You achive video crop effect using TextureView which require Android API 14 and hardware acceleration. I described it in my article here.
You can also use my TextureVideoView - custom view based on android TextureView which gives you ability to easy play and crop video. This very similar to ImageView#setScaleType
Layout
<com.dd.crop.TextureVideoView
android:id="#+id/cropTextureView"
android:layout_width="fill_parent"
android:layout_height="100dp"/>
Code
TextureVideoView cropTextureView = (TextureVideoView) findViewById(R.id.cropTextureView);
// Use `setScaleType` method to crop video
cropTextureView.setScaleType(TextureVideoView.ScaleType.TOP);
// Use `setDataSource` method to set data source, this could be url, assets folder or path
cropTextureView.setDataSource("http://www.w3schools.com/html/mov_bbb.mp4");
cropTextureView.play();
Hope this will help someone!
Source implies that it isn't natively supported in the VideoView view. You could copy the source and make it work though. :) Most likely by adding an else at line 255, modifying onMeasure to prevent it from expanding to meet the size, etc.
Edit:
Don't be surprised that the Reference documentation is slightly off or just plain wrong.
Related
The goal is to crop a preview on the surface for frames that come from Camera2 api capture session, but not to crop the video that will be created itself.
For example, I have a streaming resolution of 1920x1080 (16:9), and the screen size (just for instance) 2000x3000 (2:3 -> 6:9 or 16:24, lets pick the second variant for example), so I'd like to have my video in the original streaming resolution - 1920x1080, but my preview to fill all the available space without View resizing - so it should be 5333x3000 (just bumping the size up to fill the rectangle area using the same aspect ratio as the streaming resolution's one), and then to "cut" the "frame data that corresponds to this surface's resolution (which is, I suppose, 5333x2000)" to 2000x3000 (just remove (5333 - 2000) / 2 from both top and bottom).
Is it possible?
P.S.: the bad thing is that google sample for camera2 api resizes the view itself, and these "blank areas" are undesired for me. I haven't found anything that even closely matches my problem.
P.S.S.: AFAIU this SO solution crops the frame that comes from the camera itself, but I need my video to be in the original resolution.
If you're using a TextureView, you can probably adjust its transform matrix to scale up the preview (and cut off the edges in the process). Read the existing matrix, fix up the aspect ratio and scale it up, and then save the new matrix.
But please note that saving a different field of view than what you're showing to the user is probably going to get you negative reactions - please use the preview to frame what they want to record, and if what you're saving has extra stuff, the recorded video won't match expectations. Of course, maybe this isn't a concern for your use case.
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.
I have generated a QR code image using zxing 2.1 library, but the image is very blurry and unclear.
Where might I be possibly going wrong?
The generation happens at a lower level and then is scaled with a width and height request. You can request generation at a higher width and height.
ZXing exposes BarcodeOptions in the viewer that you can set.
In your model you can do this:
public EncodingOptions BarcodeOptions => new EncodingOptions() { Height = 100, Width = 100, PureBarcode = true };
Then in your XAML it might look like this:
<z:ZXingBarcodeImageView BarcodeFormat="QR_CODE" HeightRequest="100" WidthRequest="100" Margin="10" BarcodeValue="a long url to a thing that accepts a zing to another thing"
BarcodeOptions="{Binding BarcodeOptions}" >
Remember to update the width and height of your EncodingOptions if you change the width and height on your XAML.
I don't think there's anything wrong with the image you're creating. It's only when you're displaying it that it's coming out blurry.
You're generating a small QR code, with limited resolution in each direction. That's absolutely fine, but when it gets displayed, it needs to be scaled up appropriately. Whatever you're using to display the image (Android's default image viewer, maybe) is resampling the image and trying to reduce jagged edges. That's what you want if it's a photo, but quite inappropriate for a bar code, where you want it to be rescaled using a nearest neighbour algorithm. That way, it won't look blurry at all.
(It's hard to be absolutely certain about this unless you post the actual image rather than a screenshot, though.)
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
Android has a nice way of defining stretchable images called a nine-patch. See these docs for a description of the concept. The idea is to surround a png image with a 1-pixel border where you can define the stretchable areas and the padding dimensions of the image. This is absolutely brilliant and I'd like to use the idea in my iPhone app. Before writing my own nine-patch to UIImage loader I thought I'd see if one already exists. Google doesn't return any results so I don't have much hope, but it doesn't hurt to ask, right? :-)
EDIT: Folks, I appreciate the answers but I know about stretchableImageWithLeftCapWidth.... I'm looking for code that takes a path #"foo.9.png" and returns a stretchable UIImage. This code will undoubtedly use stretchableImageWithLeftCapWidth... internally. I'm sure I could write the code myself using that method. But I'm asking if somebody else has already done it.
I received an e-mail from Tortuga22 software who informed me that they have created such a library and released it under the Apache license:
Announcement: http://blog.tortuga22.com/2010/05/31/announcing-tortuga-22-ninepatch/
Source code: http://github.com/tortuga22/Tortuga22-NinePatch
Example usage:
// loads-and-caches ninepatch and rendered image of requested size
UIImage buttonImg = [TUNinePatchCache imageOfSize:buttonSize
forNinePatchNamed:#"buttonNormalBackground"];
[self.buttonNeedingBackground setImage:buttonImg
forControlState:UIControlStateNormal];
Also look at UIView's contentStretch property. It is more robust and well-behaved than stretchableImageWithLeftCapWidth. Basically, it works by just defining the stretchable rectangle within your image and automatically creating a scaled nine-patch. This internal rectangle can be anything - it doesn't even have to be in the center of the image. Plus unlike stretchableImage this method will properly shrink graphics and behave as expected for graphics with lighting or gloss. I can't think of any real-world application where you would want more than this.
Yes UIImage does support something like it. See
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight and the documentation for leftCapWidth and topCapHeight
basically the image is not stretched in the area leftCapWidth pixels from the left and right edge and topCapHeight pixels from the top and the bottom. When the image is scaled the area inside of these limits is subject to stretching.
All UIImage images support this natively. By default the entire images is stretchable, but you can set caps with the leftCapWidth and topCapHeight properties or you can generate one from an existing UIImage with the - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight method.
Do note that in apple's implementation, when you set one or both of these values, the stretchable area is forced to be a single pixel high/wide.