android camera stretched in landscape mode - java

The app I'm writing requires camera functionality.
So to learn about how to operate the camera, I followed this script:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html
I have put the activity in my manifest, set the screen orientation for it on landscape mode.
The problem I'm having is, when the camera is held sideways (so I hold my Galaxy Tab P1000 in landscape position) the view is stretched out.
To be more specific about my script, I used an exact copy of code that Google made. It can be found in the android-sdk\samples\android-8\ApiDemos\src\com\example\android\apis\graphics\
The file itself is called CameraPreview.
I really have no clue why the screen looks so stretched. Of course, the format is weird and not square, but still, when using the default camera app installed on the device, it doesn't deform at all. This camera deforms the image when I hold it sideways and move the camera even a little.
What I did was: I held my galaxy tab to take a picture of an object (laptop in this case) then took a picture with my phone of my Galaxy. On the Galaxy I have the camera screen open in the app i'm making. This counts for both images. One I hold sideways and one I hold in portrait view. The pics are a bit unclear but you can see that in the landscape picture, the camera has become massively wide.

I faced the same problem yesterday. After a researching "Camera" sources I found a reason for camera preview being stretched.
The reason is: SurfaceView aspect ratio (width/height) MUST be same as Camera.Size aspect ratio used in preview parameters. And if aspect ratio is not the same, you've got stretched image.
So, the fastest workaround is to set SurfaceView to size like 320px x 240px - smallest supported size from Parameters.getSupportedPreviewSizes().
Also, you can look at Camera standard application sources, it uses the custom layout for controlling the SurfaceView size (see PreviewFrameLayout.java, onMeasure() function).
Use
git clone https://android.googlesource.com/platform/packages/apps/Camera.git
to get Camera sources.

public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
camera = Camera.open();
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPictureSizes();
parameters.setPictureSize(sizes.get(0).width, sizes.get(0).height); // mac dinh solution 0
parameters.set("orientation","portrait");
//parameters.setPreviewSize(viewWidth, viewHeight);
List<Size> size = parameters.getSupportedPreviewSizes();
parameters.setPreviewSize(size.get(0).width, size.get(0).height);
camera.setParameters(parameters);
camera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need only getSupportedPreviewSizes() and save it to a List:
List<Size> size = parameters.getSupportedPreviewSizes();
parameters.setPreviewSize(size.get(0).width, size.get(0).height);
camera.setParameters(parameters);
camera.startPreview();
I hope this helps you.

Related

Fullscreen camera preview in fragment

I've spent the last two days browsing SO to find answers, unsuccessfully.
I'm trying to reproduce a Snapchat-like app.
What I have so far
A ViewPager composed of 3 fragments.
The middle fragment is supposed to display a camera preview, just like Snapchat, on the whole surface (not truly fullscreen but it should cover the entire UI between the status bar and the bottoms buttons)
I'm able to display either:
The camera preview, with the correct ratio, but not covering its parent View (see picture 1 below)
The camera preview, covering its parent View but stretched (wrong ratio)
 What I need
Avoid stretching the preview. Possibly, the preview would be cropped on both sides (left and right). See picture 2 below. I guess this is what Snapchat does. Or is there any other way?
What I went through
http://www.shakedos.com/2015/Aug/26/writing-an-android-portrait-camera-app.html
Make a SurfaceView larger than the screen (Fitting a camera preview to a SurfaceView larger than the display)
Android full screen camera - while keeping the camera selected ratio : can't find the whole code
Requirements
I need to use the Camera API version 1, not version 2.
Final photos must be taken in 4/3 format, not 16/9.
Portrait is forced although pictures can be in landscape or portrait
Thank you

How to make Wallpaper permanently fit to screen and in center?

I am trying to make the wallpaper fit to screen. I tried many solutions on this site but none worked for me except this one, but the image doesn't cover the screen. It kind of shrinks and it can appear anywhere on the screen, mostly in the center. The image size changes again on next reboot. E-g it appears in the middle and is much smaller than the screen size but when I reboot my device, the image size exceeds the bounds of the screen
How can I make it fit to the screen?
If I can't, how can I make it appear in the center permanently?
Does it depend on the dimensions (width, height) of the image too?
Below is my code:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
imageIDs[imageIDforWallPaper]);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
WallpaperManager wm = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
try {
wm.setBitmap(bitmap);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wm.suggestDesiredDimensions(w, h);
What you are looking for is similar to a splash screen.
The image shrinks because it has fixed width and height, and most probably they don't match with your device's dimensions. Every image will have a different width/height ratio, it isn't therefore a good idea trying to perfectly fit an image to one particular screen, as you may be able to do so (by modifying the image dimensions), but then you wouldn't be able to obtain the same result on every device: Devices and Displays
Create a 9-patch image which adapts to every screen: 9-patch image introduction
Yes it depends on width and height, but these values vary according to screen size and density. When you design an image you need to use dip (density-independent pixels) and create one image for each category of screen densities: Design for multiple screens
read also here: Android splash screen image sizes to fit all devices

How to show two identical camera previews with the Android camera?

I need to be able to display two identical previews from a running camera instance on screen, is this possible?
So far the only way I could think of was to clone the preview surfaceview. So using the raw video data provided to onPreviewFrame,
I am creating a new bitmap for the current frame and then drawing that to the surfaceholder canvas.
This displayed perfectly when run on the ui thread, but obviously it blocked the UI every couple of seconds whilst creating the bitmaps. I have now moved the bitmap creation into a new thread which resolves the app locking up, but now my surfaceview flickers/tears slightly!
Would this ever work? or am I going the wrong way about it? How can I stop the flicker?
Cut down sample code;
public void onPreviewFrame(byte[] data, Camera camera) {
-- new thread
// create bitmap from YUV (videoFrame)
-- UI thread
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(videoFrame, null, new Rect(0, 0, 200, 200), null);
}
} catch (Exception e) {
mLogger.error(e.getMessage());
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
I believe this is something to do with the surfaceview double buffer, I have quite a few solutions but cant stop the flicker!
If you don't need to run on Android releases before 3.0 (Honeycomb), you can use the SurfaceTexture output option, and OpenGL ES for rendering multiple previews.
Setting up a working OpenGL view is a bit involved, so you'll want to find a guide for that.
Once you have that working, create a SurfaceTexture object with a OpenGL texture ID you want to use for the preview texture, pass that into the camera with setPreviewTexture instead of using setPreviewDisplay, and then in your OpenGL thread, call updateTexImage to update the texture to show the latest frame from the camera (best to do so in response to a onFrameAvailable callback for best performance).
Then you need OpenGL code to render two rectangles for your two copies of preview, and a shader to draw the preview texture on both.
This is a decent bit of setup, but in the end, you'll have a very flexible system - then you can animate the preview in various fun ways, etc.

Camera and SurfaceView - Video Distorted / Artifacting

Screenshot: http://imgur.com/r7EpSpx
I have a very specific issue regarding the operation of a SurfaceView and a Camera. I am using the SurfaceView as the preview surface for a camera in an IntentService (to allow background operation).
After a lot of trial and error, I almost have the code working as desired. However, when I am using MediaRecorder to record video, whenever I resume my activity (thus the SurfaceView is re-created) the video is extremely distorted/artifacted in what seems to be rainbow colors with a large black rectangle in the middle. Also the video effect seems to be in a "tile" arrangement. If you look closely, the camera is still working and the video records as normal, but the SurfaceView preview is broken.
Normally, I would re-instantiate the Camera object in the surfaceCreated methods of my SurfaceView callback, but whenever I use Camera.stopPreview(), or several other Camera functions, it causes my MediaRecorder.stop() to hang indefinitely (this is another separate issue). Due to this, I must use the same Camera object in my IntentService when the surface is re-created.
Everything works as normal except this strange video distortion, even the resulting video that the MediaRecorder produces. Only the preview is affected. I am unable to determine whether this is a code issue, software issue, TouchWiz issue, or hardware issue. It occurs in all orientation configurations. Moving the code to surfaceChanged results in the same thing. Thanks in advance for any help or insight into this!
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (isRecording) //Only run this code if MediaRecorder is recording
try {
recordingCamera.setPreviewDisplay(rHolder); //This works, but causes the aforementioned distortion
//recordingCamera.startPreview(); //Removes distortion, but causes MediaRecorder.stop() to freeze app indefinitely
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
//recordingCamera.stopPreview(); //Removes distortion, but causes MediaRecorder.stop() to freeze app indefinitely
}
Running this on a Galaxy Note II | Android 4.1.2 (TouchWiz)

SurfaceView is displaying camera feed sideways

For some reason the camera feed in my program is sideways. If I hold my finger up to the camera from the bottom, it shows up as coming from the right in the surfaceview.
I have a pretty standard implementation
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(surfaceCallback);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
I've looked around but I can't seem to find any information on this. My device is a nexus One.
EDIT: If I set the screen orientation to landscape then it works fine for some reason... Can't get it in portrait though.
The orientation of the preview display image is controlled by Camera.setDisplayOrientation(int) method. For my Evo, setting the orientation to 90 makes the preview display correct for portrait mode.
...
camera.setParameters(parameters);
camera.setDisplayOrientation((orientation+90)%360);
camera.startPreview();
...
It seems that changing the orientation after the preview is started causes an exception. If you change rotate the phone/device, the SurfaceHolder.surfaceChanged callback will be called again, if you do the setDisplayOrientation and startPreview in that callback, you get an exception. I'm, going to try stopping preview, then changing the orientation then starting it again.
Note: There is also the Camera.Parameters.setRotation(int) method, that (I think) changes the orientation of the image when it is written into the (JPEG) output image when a picture is taken. This method does not change the preview display orientation.
use this line
mCamera.setDisplayOrientation(90);
in surfaceCreated method after
mCarmera.open();

Categories

Resources