3

I have developed a android camera application using this tutorialspoint tutorial
My purpose is that on opening app i will enter a text which i want to be shown on taking image
I am using a surface view to display the image preview while capturing but now i want to display a text on screen while taking image(live)
this answer seems to draw the text after capturing the image i.e on saving image but i want to display the text while taking the picture
position of the text should be fixed
And yes i want to get that text saved in image on saving i.e. i don't want to only show the text but it should also get saved in image
I have'nt posted any code as it is same as in link but i will update the question when needed
Thank you.

Code(MainActivity.java):

  package com.campg.sonix.campgs;

  import android.content.res.Configuration;
  import android.hardware.Camera;
  import android.hardware.Camera.PictureCallback;
  import android.hardware.Camera.ShutterCallback;

  import android.hardware.SensorManager;
  import android.media.ExifInterface;
  import android.os.BatteryManager;
  import android.support.v7.app.ActionBarActivity;
  import android.os.Bundle;

  import android.support.v7.app.AppCompatActivity;
  import android.util.Log;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.OrientationEventListener;
  import android.view.Surface;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  import android.view.View;


  import android.widget.Toast;

  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;

  import java.util.ArrayList;
  import java.util.Set;


  public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
      Camera camera;
      SurfaceView surfaceView;
      SurfaceHolder surfaceHolder;
      OrientationEventListener orientationEventListener;
      Camera.PictureCallback rawCallback;
      Camera.ShutterCallback shutterCallback;
      Camera.PictureCallback jpegCallback;
      private Camera.Size csize;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          orientationEventListener
                  = new OrientationEventListener(this,  SensorManager.SENSOR_DELAY_NORMAL){

              @Override
              public void onOrientationChanged(int orientation) {
                  // TODO Auto-generated method stub
                 try {
                     if (orientation == ORIENTATION_UNKNOWN) return;
                     android.hardware.Camera.CameraInfo info =
                             new android.hardware.Camera.CameraInfo();
                     android.hardware.Camera.getCameraInfo(i, info);
                     orientation = (orientation + 45) / 90 * 90;
                     int rotation = 0;
                     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                         rotation = (info.orientation - orientation + 360) % 360;
                     } else {  // back-facing camera
                         rotation = (info.orientation + orientation) % 360;
                     }
               Camera.Parameters mParameters;
               mParameters = camera.getParameters();
               mParameters.setRotation(rotation);

               Log.d("orientation is",String.valueOf(orientation));

           }
           catch (Exception e)
           {
               Log.e("orien exc", "exception", e);

           }

        }};

    if (orientationEventListener.canDetectOrientation()){
        Toast.makeText(this, "Can DetectOrientation", Toast.LENGTH_LONG).show();
        orientationEventListener.enable();
    }
    else{
        Toast.makeText(this, "Can't DetectOrientation", Toast.LENGTH_LONG).show();
        finish();
    }
    Log.i("oncre","ate");
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);

    surfaceHolder = surfaceView.getHolder();
    Log.i("ya", "ya");

    surfaceHolder.addCallback(this);
    Log.i("ya1", "ya2");

    surfaceHolder.setType(surfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    Log.i("ya3", "ya4");

    jpegCallback = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outputStream =null;

            try {
                outputStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                outputStream.write(data);
                outputStream.close();
                Log.i("yaha1", "yaha1");

                Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
            }
            catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            catch (IOException e) {
                Log.e("hii2", "exception", e);
                e.printStackTrace();
            }  finally {
            }
            Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_LONG).show();
            refreshCamera();
        }
    };
}

public void captureImage(View v) throws IOException {
    try {
        camera.takePicture(null, null, jpegCallback);

    }
    catch (NullPointerException e)
    {
        Log.i("m here", "m here");

        Log.e("hey br", "exception", e);

    }
    catch (IllegalStateException e)
    {
        Log.e("hii 12 4", "exception", e);

    }
    catch (RuntimeException e)
    {
        Log.e("hii 12 4", "exception", e);

    }

}

public void refreshCamera()
{
        if(surfaceHolder.getSurface() == null)
            return;
    try
    {
        camera.stopPreview();
    }
    catch (Exception e)
    {
    }
    try
    {
    camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    return true;
}
@Override
protected void onDestroy()
{
    super.onDestroy();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    return super.onOptionsItemSelected(item);
}
public static void setCameraDisplayOrientation(MainActivity activity,
                                               int cameraId, Camera camera) {
   try
   {
    Log.i("inside", "inside");

    android.hardware.Camera.CameraInfo info =
            new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay()
            .getRotation();
    int degrees = 0;
    switch (rotation) {
        case Surface.ROTATION_0: degrees = 0; break;
        case Surface.ROTATION_90: degrees = 90; break;
        case Surface.ROTATION_180: degrees = 180; break;
        case Surface.ROTATION_270: degrees = 270; break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
   }
   catch (Exception e) {
       Log.e("inside", "exception", e);
   }
}



int i;

@Override
public void surfaceCreated(SurfaceHolder holder)
{

    try {
        camera=Camera.open(i);
        camera.setDisplayOrientation(180);

        Log.i("m here", "m here");

    }
    catch (RuntimeException e) {
        System.err.println(e);
        Log.e("hey", "exception", e);

        return;
    }
    Log.i("aftr", "aftr");
    try
    {
        Camera.Parameters param;
        param = camera.getParameters();
        String currentversion = android.os.Build.VERSION.SDK;
        Log.d("System out", "currentVersion " + currentversion);
        int currentInt = android.os.Build.VERSION.SDK_INT;
        Log.d("System out", "currentVersion " + currentInt);
        param.set("orientation", "portrait");

      if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            if (currentInt != 7) {
                camera.setDisplayOrientation(90);
            } else {
                Log.d("System out", "Portrait " + currentInt);

                param.setRotation(90);


              param.set("orientation", "portrait");
              param.set("rotation",90);

                camera.setParameters(param);
            }
        }
       if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // camera.setDisplayOrientation(0);
            if (currentInt != 7) {
                camera.setDisplayOrientation(0);
            } else {
                Log.d("System out", "Landscape " + currentInt);
                param.set("orientation", "landscape");
                param.set("rotation", 90);
                camera.setParameters(param);
            }
        }

        param.setPreviewSize(288,352 );
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
        Toast.makeText(getApplicationContext(), "hi 2", Toast.LENGTH_LONG).show();
    }
    catch (Exception e) {
        System.err.println(e);
        return;
    }

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{

    try
{
    setCameraDisplayOrientation(this,i,camera);
    refreshCamera();
    Log.i("inside sfc", "inside sfc");

}
catch (Exception e) {
    Log.e("surfacechan", "exception", e);
    System.err.println(e);
    return;
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    try {
        camera.stopPreview();
        camera.release();
        camera = null;
    }
    catch (Exception e){
        System.err.println(e);
        return;
    }

    }}


Manifest:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.campg.sonix.campgs"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"

        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Xml file:-

<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="match_parent"
android:layout_margin="3dp"
android:layout_height= "0dp"
android:layout_weight="1" />

<LinearLayout
android:id="@+id/capture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="captureImage"
android:clickable="true"
android:orientation="vertical"
android:gravity="center"
 >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Capture"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

Community
  • 1
  • 1

2 Answers2

1

For adding text on preview,

1) Extend the Surfaceview class

2) Add the Text (or button etc) by overriding the onDraw() call

For ex, create a new class CameraOverlaySurfaceView, (instead of SurfaceView surfaceView; in your code):

public class CameraOverlaySurfaceView extends SurfaceView {
public CameraOverlaySurfaceView(Context ctx)  { /* Do init */
    super(ctx);
    setWillNotDraw(false);
}

@Override
protected void onDraw(Canvas canv) { 
  /* Draw text like in 
  http://stackoverflow.com/questions/2655402/android-canvas-drawtext
 */
}

For saving text along with captured image as file,

1) In the jpegcallback, you will have to manually add the Text bitmap at the required location, and re-encode and store.

Prabindh
  • 3,356
  • 2
  • 23
  • 25
  • I started learning android a week ago, can you please provide a code or any link from where i can refer because just by reading your answer i am not able to understand what is to be done as my android concepts are not yet developed that much...Thank You, – Priyanka Ambavale Jun 20 '16 at 13:47
  • Added snippet in answer to help. – Prabindh Jun 20 '16 at 14:00
  • ,,i have a silly doubt that braces in your ans are not closed properly i.e the ondraw will come inside the extended surface view class and this ( public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback ) in my code will not have any affect right? – Priyanka Ambavale Jun 20 '16 at 14:06
  • also in extended class in /*do init */ what should be initialized exactly ?? :( Sorry for so many doubts. – Priyanka Ambavale Jun 20 '16 at 14:14
  • There are enough pointers in the snippet to get you started. Rest you should figure out on your own along with basic study. Just try and have fun. – Prabindh Jun 20 '16 at 14:24
  • just 1 question ,when i tried to use public class CameraOverlaySurfaceView extends SurfaceView it said to be included in other java file but when i made then the problem was it was not getting called – Priyanka Ambavale Jun 20 '16 at 14:33
0

Whatever you decide to do, displaying text with preview and embedding text into captured picture are two independent tasks. You can build your app such that for the end user the experience is just that the text in the preview screen is captured in the photo, but this will still only be an illusion.

One caveat is to make sure that the captured picture aspect ratio is the same as of preview display. Make sure that you use the same font. Scaling the text is not trivial, because screen resolution is usually much lower than captured picture, and some fonts must be excluded because they don't scale well. Printing text on photo background should involve antialiasing.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • I started learning android a week ago, can you please provide a code or any link from where i can refer because just by reading yours and prabindh's answer i am not able to understand what is to be done as my android concepts are not yet developed that much,Also i don't know what is antialiasing...Thank You, – Priyanka Ambavale Jun 20 '16 at 13:46
  • You have the link in your question that has a [very good answer](http://stackoverflow.com/a/10313272/192373) about drawing text on bitmap with antialiasing. If you don't know what it is about, look up your computer graphics textbook. There is pretty much to be studied to make text look good both on screen and over the captured photo. Regarding Android programming, running camera, *etc.* you can probably take an online course. – Alex Cohn Jun 20 '16 at 18:10
  • yes now i have my code drawing the text(using canvas.drawText(..)) while saving the image but i am having hard time showing that text on the preview(live camera).... – Priyanka Ambavale Jun 20 '16 at 19:09