0

My custom camera result image quality is poor comparing to system camera using camera2 api.

My app is based on Camera2Basic example. and all modes are set to auto and using the largest available size.

JPEG Results:

Custom Camera: 3984x2988, 630KB

Native Camera: 3984x2988, 2.73MB

All the open source examples have almost same output. Is there any way to get better output? Any help would be appreciated!

mudin
  • 2,672
  • 2
  • 17
  • 45

6 Answers6

1

Please have a look at CameraView. This is a custom Camera implementation, I think It will give you a proper place to start.

raktale
  • 465
  • 3
  • 12
  • I have tested their demo and result is not as I expected :( – mudin Feb 09 '17 at 06:00
  • It is working, but my question is why the image quality is not as high as native camera 's quality – mudin Feb 09 '17 at 06:04
  • 2
    Well, where to start, Native camera app can have a lot of optimizations done via post processing, It also depends on the manufacturer as Camera is a feature that is given the a lot of attention. Then there are HDR modes or other modes for that matter that use different techniques to adjust light exposure.Long story short my advice would be if you are wondering why high quality you should check for the device specific optimizations done for the device you are using. – raktale Feb 09 '17 at 06:11
  • Yes right, I believe it cannot be same as native camera. – mudin Feb 09 '17 at 06:16
  • Should I process raw sensor image to get better result? – mudin Feb 09 '17 at 06:18
  • Well that would be the way to go in my opinion as well. http://stackoverflow.com/questions/14777953/how-to-capture-raw-image-from-android-camera this link might get you started. – raktale Feb 09 '17 at 06:38
  • I was looking for ready open source example for this. Seems like I have to do to more research – mudin Feb 09 '17 at 07:10
1

There is this great open camera application. It is open source and you can check how he did image saving. I think your problem is image saving. Your image is so small than original and that's why your image is low quality. Here is open camera website http://opencamera.sourceforge.net/ . Open camera support camera api 1 and api 2.

Maxitors
  • 236
  • 2
  • 8
0

Here is the app for using the full resolution of your camera:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.osahub.rachit.highrescamera"
      xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".CameraActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

CameraActivity.java

package com.osahub.rachit.highrescamera;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ShareActionProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;

public class CameraActivity extends AppCompatActivity {

    ImageView image;
    Button camera;
    Uri imageUri;
    private String folderPath = Environment.getExternalStorageDirectory()
        .getPath() + "/CameraActivity/images";
    private File file;

    private ShareActionProvider mShareActionProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        camera = (Button) findViewById(R.id.camera);
        image = (ImageView) findViewById(R.id.image);
        File folder = new File(folderPath);
        folder.mkdirs();

        file = new File(folder.getPath() + "/image.jpg");
        camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageUri = Uri.fromFile(file);
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, 10);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            Bitmap bp = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
            Matrix rotateMatrix = new Matrix();
            rotateMatrix.postRotate(90);
            Bitmap rotatedBitmap = Bitmap.createBitmap(bp, 0, 0, bp.getWidth(),
                bp.getHeight(), rotateMatrix, false);
            camera.setVisibility(View.GONE);
            image.setImageBitmap(rotatedBitmap);
            setShareIntent(createShareIntent());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_camera, menu);

        MenuItem item = menu.findItem(R.id.action_share);
        mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);

        setShareIntent(createShareIntent());
        return true;
    }

    private void setShareIntent(Intent shareIntent) {
        if (mShareActionProvider != null) {
            mShareActionProvider.setShareIntent(shareIntent);
        }
    }

    private Intent createShareIntent() {
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
        shareIntent.setType("image/*");
        return shareIntent;
    }
}

activity_camera.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                tools:context=".CameraActivity">

    <Button
        android:id="@+id/camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="@string/open_camera"/>

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignTop="@+id/camera"
        android:contentDescription="@string/image_description"/>
</RelativeLayout>
Rachit
  • 3,173
  • 3
  • 28
  • 45
0

After some research I found solution. This github code helped me a lot: https://github.com/webjb/myrobot

I am taking image from camera with YUV_420_888 format and passing its byte buffer to opencv using NDK, and opencv saves as jpeg.

Quality is high and file size is more than 2MB!

mudin
  • 2,672
  • 2
  • 17
  • 45
  • @muddin, Hi there mate, I know this thread was written a long time ago (at the beginning of Jan 2017) but I'm in a very similar situation as what you described in your problem right now. I'm trying to make a camera application but for some reason the output's file size is way smaller than native camera app output and it looks a bit blurry/low quality. That's why I came to this thread and I saw your comment right here ^^ . but I have no idea what opencv/NDK is and what is this YUV_420_888 image format. Is there any guide out there that I can follow to help me improve the output image quality? – blue2609 May 01 '19 at 06:49
0

I found other solution. This is the best one. I simply using samsung camera sdk. It is very awesome, and results are much better than custom camera, almost same as native camera app.

mudin
  • 2,672
  • 2
  • 17
  • 45
0

The one quick solution is that you can use Camera Parameters to set only orientation but not set the height and width of the image. Like this.

if (this.getResources().getConfiguration().orientation!= Configuration.ORIENTATION_LANDSCAPE) {
    params.set("orientation","portrait");
    camera.setDisplayOrientation(90);
    params.setRotation(90);
} else {
    params.set("orientation","landscape");
    camera.setDisplayOrientation(0);
    params.setRotation(0);
}
// params.setPictureSize(msize.width,msize.height);
camera.setParameters(params);`

I got the key help from this post.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31