我正在使用Camera API并调用相机。
我想在相机预览的顶部显示标题(用于标记)。标题是jpeg图像。
有可能吗?任何帮助表示赞赏。
提前致谢。
我的代码如下。
public class CameraActivity extends Activity {
@Override
protected void onPause() {
super.onPause();
}
private static final int CAMERA_PIC_REQUEST = 2500;
private Bitmap image2;
private Bitmap bm;
public static String imagepath;
public static int x=1;
private RdmsDbAdapter dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.header);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//caling new incident
if(IncidentFormActivity.incident_id == null || IncidentFormActivity.isDisable==true){
//DBAdapter instance created and connection opened.
dbHelper = new RdmsDbAdapter(CameraActivity.this);
dbHelper.open();
//setting up flags
NewIncidentHelper nih = new NewIncidentHelper();
nih.setUpNewIncident();
//setting up incident_id
String Date= IncidentIdGenerator.getDate();
String Time = IncidentIdGenerator.getTime();
IncidentFormActivity.incident_id = IncidentIdGenerator.now("ddMMyyyyHHmmss");
dbHelper.executeSQL("insert into incident values ('" + IncidentFormActivity.incident_id
+ "', ' ', ' ', ' ', ' ', '"+Date+"', '0','0','0','0','0','0','0','0','0','"+Time+"')");
dbHelper.close();
}
//calling camera
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
//back key on phone pressed
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
Intent i= new Intent(CameraActivity.this, IncidentFormActivity.class);
startActivity(i);
this.finish();
break;
default:
break;
}
return super.onKeyDown(keyCode, event);
}
//handle response came from camera when the picture is taken.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
final ImageView img = new ImageView(this);
img.setLayoutParams(new LayoutParams(100, 100));
image2 = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(image2);
String incident_ID = IncidentFormActivity.incident_id;
//l2.addView(img);
imagepath="/sdcard/RDMS/"+incident_ID+ x + ".png";
File file = new File(imagepath);
try {
bm = Bitmap.createScaledBitmap( image2,400, 300, true);
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bm.compress(CompressFormat.PNG, 90, ostream);
ostream.close();
//Initialising db class and inserting values
dbHelper = new RdmsDbAdapter(CameraActivity.this);
dbHelper.open();
dbHelper.executeSQL("insert into files values ('"+imagepath+"', '"+IncidentFormActivity.incident_id+"')");
dbHelper.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"yourfirst error message is "
+ e.toString(), 1000).show();
}
x++;
final AlertDialog.Builder alert = new AlertDialog.Builder(
CameraActivity.this);
alert.setTitle(getString(R.string.anotherimage));
alert.setCancelable(false);
//alert.setMessage("Play or Delete the Video selected");
//alert.setIcon(R.drawable.vid_red);
alert.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent sendingpage = new Intent(CameraActivity.this, CameraActivity.class);
startActivity(sendingpage);
}
});
alert.setNegativeButton(getString(R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent callback = new Intent (CameraActivity.this, IncidentFormActivity.class);
startActivity(callback);
}
});
alert.show();
}
if(resultCode==RESULT_CANCELED)
{
AlertDialog.Builder builder = new AlertDialog.Builder(CameraActivity.this);
builder.setMessage(getString(R.string.areuexit)).setCancelable(
false).setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent i= new Intent(CameraActivity.this, IncidentFormActivity.class);
startActivity(i);
CameraActivity.this.finish();
}
}).setNegativeButton(getString(R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
Intent i= new Intent(CameraActivity.this, CameraActivity.class); startActivity(i);
CameraActivity.this.finish();
}
});
builder.show();
}
}
}
答案 0 :(得分:21)
您可以使用SurfaceView并创建一个将打开相机的CustomView,您可以相应地调整xml中的大小。下面是伪代码。
创建一个扩展SurfaceView并在其中打开相机的类
CapturePreview.java
public class CapturePreview extends SurfaceView implements SurfaceHolder.Callback{
public static Bitmap mBitmap;
SurfaceHolder holder;
static Camera mCamera;
public CapturePreview(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.getSupportedPreviewSizes();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
/***
*
* Take a picture and and convert it from bytes[] to Bitmap.
*
*/
public static void takeAPicture(){
Camera.PictureCallback mPictureCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
BitmapFactory.Options options = new BitmapFactory.Options();
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
};
mCamera.takePicture(null, null, mPictureCallback);
}
}
现在您必须在xml中包含使用SurfaceView创建的视图
<强> main.xml中强>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="@+id/mySurfaceView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.cam.CapturePreview
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</com.cam.CapturePreview>
</FrameLayout>
<LinearLayout
android:layout_below="@id/mySurfaceView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center">
<ImageView android:id="@+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"/>
</LinearLayout>
</RelativeLayout>
现在,您可以在任何Acitivty
中使用此main.xml,它将打开一个ImageView
的摄像头。
感谢....
答案 1 :(得分:20)
您必须自己处理整个相机预览并拍照。请查看samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview
处的示例。您可以在预览区域上拥有自己的布局,并将图形添加到其中。
https://developer.android.com/training/camera/cameradirect#java
答案 2 :(得分:3)
你可以在FrameLayout
的帮助下这样做:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.view.SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageView
android:id = "@+id/header"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" />
</FrameLayout>
此camera project会对您有所帮助。
答案 3 :(得分:1)
我担心你必须亲自实现相机预览屏幕。理论上,可以通过修改其布局或创建叠加窗口将叠加添加到其他应用程序。第一种方式是不可能实现的,我认为第二种方式可以实现,但它是一种黑客攻击和容易出错的方法。
实施自己的相机活动并不是一件非常困难的事情,但它具有相当的挑战性。我建议你看一下默认的Camera应用程序。这是源代码:https://github.com/android/platform_packages_apps_camera。
答案 4 :(得分:0)
看看你的XML会是这样的:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.view.SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageView
android:id = "@+id/header"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" />
</FrameLayout>
对于java代码,你应该在你的活动中扩展SurfaceHolder.Callback,然后将相机附加到像这样的表面视图,它的完整代码请注意位图和画布,这是一个棘手的部分:
public class MainActivity extends Activity implements SurfaceHolder.Callback
{
private Camera camera = null;
private SurfaceView cameraSurfaceView = null;
private SurfaceHolder cameraSurfaceHolder = null;
private boolean previewing = false;
RelativeLayout relativeLayout;
private Button btnCapture = null;
private Button btnsave = null;
private Button btnshare = null;
private boolean isSaved=false;
private boolean isCaptured=false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
relativeLayout=(RelativeLayout) findViewById(R.id.containerImg);
relativeLayout.setDrawingCacheEnabled(true);
cameraSurfaceView = (SurfaceView)
findViewById(R.id.surfaceView1);
// cameraSurfaceView.setLayoutParams(new FrameLayout.LayoutParams(640, 480));
cameraSurfaceHolder = cameraSurfaceView.getHolder();
cameraSurfaceHolder.addCallback(this);
// cameraSurfaceHolder.setType(SurfaceHolder.
// SURFACE_TYPE_PUSH_BUFFERS);
btnCapture = (Button)findViewById(R.id.capturebtn);
btnCapture.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
camera.takePicture(cameraShutterCallback,
cameraPictureCallbackRaw,
cameraPictureCallbackJpeg);
isCaptured=true;
}
});
btnsave = (Button)findViewById(R.id.savebtn);
btnsave.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
FrameLayout frm = (FrameLayout)findViewById(R.id.frameLayout1);
frm.setDrawingCacheEnabled(true);
frm.buildDrawingCache();
Bitmap bitmap = frm.getDrawingCache();
try {
File rootFile=new File(Environment.getExternalStorageDirectory().toString()+"/MYCAMERAOVERLAY");
rootFile.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".png";
File resultingfile = new File(rootFile, fname);
if (resultingfile.exists ()) resultingfile.delete ();
try {
FileOutputStream Fout = new FileOutputStream(resultingfile);
bitmap.compress(CompressFormat.PNG, 100, Fout);
Fout.flush();
Fout.close();
} catch (FileNotFoundException e) {
Log.d("In Saving File", e + "");
}
} catch(IOException e){
Log.d("In Saving File", e + "");
}
isSaved=true;
}
});
btnshare = (Button)findViewById(R.id.sharebtn);
btnshare.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if((isSaved)&&(isCaptured)){
// TODO sharing what ever we saved
// take the path
}
}
});
}
ShutterCallback cameraShutterCallback = new ShutterCallback()
{
@Override
public void onShutter()
{
// TODO Auto-generated method stub
}
};
PictureCallback cameraPictureCallbackRaw = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
// TODO Auto-generated method stub
}
};
PictureCallback cameraPictureCallbackJpeg = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
// TODO Auto-generated method stub
Bitmap cameraBitmap = BitmapFactory.decodeByteArray
(data, 0, data.length);
int wid = cameraBitmap.getWidth();
int hgt = cameraBitmap.getHeight();
// Toast.makeText(getApplicationContext(), wid+""+hgt, Toast.LENGTH_SHORT).show();
Bitmap newImage = Bitmap.createBitmap
(wid, hgt, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
camera.startPreview();
newImage.recycle();
newImage = null;
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
}
};
@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height)
{
// TODO Auto-generated method stub
if(previewing)
{
camera.stopPreview();
previewing = false;
}
try
{
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(640, 480);
parameters.setPictureSize(640, 480);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(-90);
}
// parameters.setRotation(90);
camera.setParameters(parameters);
camera.setPreviewDisplay(cameraSurfaceHolder);
camera.startPreview();
previewing = true;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
// TODO Auto-generated method stub
try
{
camera = Camera.open();
}
catch(RuntimeException e)
{
Toast.makeText(getApplicationContext(), "Device camera is not working properly, please try after sometime.", Toast.LENGTH_LONG).show();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
try{
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}catch(Exception e){
e.printStackTrace();
}
}
}
我认为现在我也应该给你完整的XML部分。所以这是:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:id="@+id/containerImg"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android1:layout_gravity="bottom"
android:orientation="vertical"
android1:gravity="bottom" >
<FrameLayout
android:id="@+id/frameLayout1"
android1:layout_width="wrap_content"
android1:layout_height="wrap_content"
android:gravity="center|top"
>
<SurfaceView
android1:id="@+id/surfaceView1"
android1:layout_width="100dip"
android1:layout_height="150dip"
android1:layout_gravity="center_horizontal" />
<ImageView
android1:id="@+id/imageView1"
android1:layout_width="fill_parent"
android1:layout_height="fill_parent"
android:contentDescription="@string/app_dress_desc"
android:gravity="center|bottom"
android1:scaleType="center"
android1:src="@drawable/dress" />
</FrameLayout>
<GridLayout
android1:id="@+id/gridLayout1"
android1:layout_width="match_parent"
android1:layout_height="wrap_content"
android1:layout_alignParentBottom="true"
android1:layout_alignParentLeft="true"
android1:columnCount="1"
android1:gravity="center|bottom"
android1:orientation="vertical" >
<ImageButton
android1:id="@+id/capturebtn"
android1:layout_width="60dp"
android1:layout_height="wrap_content"
android1:layout_gravity="left"
android1:src="@drawable/camera"
android:contentDescription="@string/app_icon_camera_desc" />
<ImageButton
android1:id="@+id/savebtn"
android1:layout_width="60dp"
android1:layout_height="wrap_content"
android1:layout_column="0"
android1:layout_gravity="center_horizontal|top"
android1:layout_row="0"
android1:src="@drawable/save"
android:contentDescription="@string/app_icon_save_desc" />
<ImageButton
android1:id="@+id/sharebtn"
android1:layout_width="60dp"
android1:layout_height="wrap_content"
android1:layout_column="0"
android1:layout_gravity="right|top"
android1:layout_row="0"
android1:src="@drawable/share"
android:contentDescription="@string/app_icon_share_desc" />
</GridLayout>
共享按钮此时不起作用,但它会在单击捕获时保存整个框架布局。 希望它会有所帮助。
答案 5 :(得分:0)
替代方法是将Activity XML文件与另一个包含标题图像的XML文件重叠。为此:
overlay.xml
在其中插入ImageView
,例如:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/imageView1"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/android" />
</RelativeLayout>
然后在Activity java文件中,即MotionDetector.java
文件,
创建一个新方法addView()
:
private void addView()
{
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.overlay, null);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(viewControl, layoutParamsControl);
}
最后从addView()
调用onCreate()
方法添加图片:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.header);
addView();
然后,最终结果将是SurfaceView
上方的图像覆盖。根据标题图像的质量,标题的渲染质量应该看起来是原始的。希望它有所帮助。