Reputation: 1370
I have made my own custom camera. This gives me bad pixelated image, I don't know why. I ma using JPEG compressing with 100 quality. And this is the Image I get Camera picture
This is my code:
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Context mContext;
private Camera.Parameters parameters;
private byte[] mBuffer;
public CameraSurfaceView(Context context) {
super(context);
mContext = context;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
if (CameraConfigurationUtils.mCameraInstance != null) {
CameraConfigurationUtils.mCameraInstance.setDisplayOrientation(90);
CameraConfigurationUtils.mCameraInstance.setPreviewDisplay(holder);
parameters = CameraConfigurationUtils.mCameraInstance.getParameters();
if (android.os.Build.VERSION.SDK_INT >= 14) {
CameraConfigurationUtils.setFocus(parameters, true, true, false);
} else {
CameraConfigurationUtils.setFocus(parameters, true, true, true);
}
WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point theScreenResolution = new Point();
theScreenResolution.set(display.getHeight(), display.getWidth());
CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution);
CameraConfigurationUtils.mCameraInstance.setParameters(parameters);
updateBufferSize();
CameraConfigurationUtils.mCameraInstance.addCallbackBuffer(mBuffer);
CameraConfigurationUtils.mCameraInstance.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
public synchronized void onPreviewFrame(byte[] data, Camera c) {
if (CameraConfigurationUtils.mCameraInstance != null) {
CameraConfigurationUtils.mCameraInstance.addCallbackBuffer(mBuffer);
}
}
});
CameraConfigurationUtils.startPreview(mContext);
}
} catch (IOException e) {
e.printStackTrace();
CameraConfigurationUtils.releaseCamera();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
mHolder.removeCallback(this);
CameraConfigurationUtils.stopPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
return;
}
try {
CameraConfigurationUtils.mCameraInstance.setPreviewDisplay(mHolder);
CameraConfigurationUtils.startPreview(mContext);
} catch (Exception e) {
CameraConfigurationUtils.releaseCamera();
}
}
public byte[] getPic(int x, int y, int width, int height) {
System.gc();
Camera.Size s = parameters.getPreviewSize();
YuvImage yuvimage = new YuvImage(mBuffer, ImageFormat.NV21, s.width, s.height, null);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(x, y, width, height), 100, outStream); // make JPG
yuvimage = null;
System.gc();
return outStream.toByteArray();
}
private void updateBufferSize() {
mBuffer = null;
System.gc();
// prepare a buffer for copying preview data to
int h = parameters.getPreviewSize().height;
int w = parameters.getPreviewSize().width;
int bitsPerPixel = ImageFormat.getBitsPerPixel(parameters.getPreviewFormat());
mBuffer = new byte[w * h * bitsPerPixel / 8];
//Log.i("surfaceCreated", "buffer length is " + mBuffer.length + " bytes");
}
}
What am i doing wrong ?
Upvotes: 1
Views: 658
Reputation: 730
Your picture example looks just like a regular lower resolution preview image feed from the camera, but I can see that in a high resolution screen it will show up pixelated. I believe your problem lies in this part of the code:
CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution);
CameraConfigurationUtils.mCameraInstance.setParameters(parameters);
It looks like you are just calculating the best preview size, which is being returned to you but you are not setting it as the actual preview size. Try it like this:
Point bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution);
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
CameraConfigurationUtils.mCameraInstance.setParameters(parameters);
Another thing is that if your intention is to take a high resolution picture you should not do it with your getPic()
method because it is just getting a preview frame as a jpeg, which is a lower resolution image. You should look into Camera#takePicture method for that.
Upvotes: 2