在拍摄图像时在相机上绘制文字

时间:2016-06-19 17:11:20

标签: android android-camera drawtext

我使用this tutorialspoint教程开发了一个Android相机应用程序
我的目的是在打开应用程序时,我将输入一个我希望在拍摄图像时显示的文本
我正在使用表面视图在捕获时显示图像预览,但现在我想在拍摄图像时显示屏幕上的文本(实时)左this答案似乎在捕获图像后绘制文本保存图像,但我想在拍照时显示文字
文字的位置应固定
是的,我希望保存图像中保存的文本,即我不想只显示文本,但它也应保存在图像中
我没有发布任何代码,因为它与链接相同,但我会在需要时更新问题 谢谢。

代码(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;
    }

    }}


清单:

    <?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文件: -     

<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>

2 个答案:

答案 0 :(得分:1)

在预览时添加文字

1)扩展Surfaceview类

2)通过覆盖onDraw()调用

添加文本(或按钮等)

例如,创建一个新类CameraOverlaySurfaceView,(而不是代码中的 SurfaceView surfaceView; ):

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
 */
}

将文本与捕获的图像一起保存为文件,

1)在jpegcallback中,您必须在所需位置手动添加Text位图,然后重新编码并存储。

答案 1 :(得分:0)

无论您决定做什么,显示带预览的文本并将文本嵌入到捕获的图片中都是两项独立的任务。您可以构建您的应用程序,以便最终用户体验只是预览屏幕中的文本被捕获在照片中,但这仍然只是一种错觉。

需要注意的是确保捕获的图片宽高比与预览显示相同。确保使用相同的字体。缩放文本并非易事,因为屏幕分辨率通常远低于捕获的图片,并且必须排除某些字体,因为它们不能很好地扩展。在照片背景上打印文本应该涉及抗锯齿。