我正在尝试使用相机应用来测量相机预览的特定区域中的像素颜色。为此,用户在摄像机预览上具有网格,该网格指示将要测量哪个特定区域。由于我想要有很好的分辨率,我不想直接从带有预览的surfaceView进行测量,但是我想在拍完照片后对照片进行测量,那么我必须对布局进行一些调整。和图片大小,位置和规则3,以便从预览尺寸到实际图片尺寸。
我使用的相机活动如下所示:
Android Camera Preview Stretched
略微修改,以确保预览和最终图片的比例相同。
我添加了一小段代码,用于保存图片的片段,该片段应该在网格下面作为位图。这就是我的问题,我不知道我在这里做错了什么,因为保存的图片与相机预览中网格下的图片不对应。 (它或多或少地向右和向右移动。)
1)请您指出我这是否是正确的做法,而在否定的情况下,您会使用哪种近似值?
2)为了为surfaceView camera_view(持有相机预览的那个)设置合适的尺寸,我想检索最佳预览尺寸的大小和比例,这是通过CameraPreview类在Camera.Size getOptimalPreviewSize上计算。要做到这一点,需要启动摄像头,据我所知,当onCreate方法已经发生时会发生这种情况。
在哪里可以放入camera_view.setLayoutParams(new FrameLayout.LayoutParams(x,y)),以便在检索到OptimalPreviewSize后调用它?
非常感谢你!
MainActivity.onCreate
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
verticalSeekBar = (VerticalSeekBar) findViewById(R.id.vertical_Seekbar);
verticalSeekBar.setOnSeekBarChangeListener(zoomSeekBarListener);
shotButton = (Button) findViewById(R.id.shotButton);
shotButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (myCameraView.safeToTakePicture)
myCamera.takePicture(null, null, jpegCallback);
myCameraView.safeToTakePicture = false;
return false;
}
});
try {
myCamera = Camera.open();
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (myCamera != null) {
myCameraView = new CameraView(this, myCamera);//create a SurfaceView to show camera data
camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(myCameraView);//add the SurfaceView to the layout
}
}
MainActivity.PictureCallback
调整大小计算在这里完成,所以这可能是我看不到的错误......
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
int viewH = camera_view.getHeight();
int viewW = camera_view.getWidth();
ImageView grid = (ImageView) findViewById(R.id.grid);
int x = grid.getRight(); //As image is rotated 90º, the right side of the grid will be the top side after Bitmap generation
int y = grid.getTop();
int relation = bitmap.getWidth()/ camera_view.getLayoutParams().height; //Relation between width of bitmap and height of surfaceview tells the relation between sizes of surfaceView and bitmap
int scaled_x = relation * y; //Theoretical position of the grid in the bitmap
int scaled_y = relation * x;
int scaledWidth = grid.getWidth() * relation;
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap resizedbitmap = Bitmap.createBitmap(bitmap, scaled_x, scaled_y, scaledWidth, scaledWidth, matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resizedbitmap.compress(Bitmap.CompressFormat.JPEG, 70, bos);
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/camtest");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
myCameraView.safeToTakePicture = true;
if (outFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(outFile);
bos.writeTo(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
CameraPreview.onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
float ratio;
if (mPreviewSize.height >= mPreviewSize.width)
ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
else
ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
Log.i(TAG, "Ratio Preview " + ratio);
getOptimalPictureSize(ratio);
// One of these methods should be used, second method squishes preview slightly
setMeasuredDimension((int) (width), (int) (width * ratio));
_width = mPreviewSize.width;
_height = mPreviewSize.height;
waitFlag = false;
}
CameraPreview.getOptimalPictureSize
private void getOptimalPictureSize(float ratio) {
List<Camera.Size> pictureSizes = mCamera.getParameters().getSupportedPictureSizes();
int lastWidth = 0;
int candidate = 0;
for (int i = 0; i < pictureSizes.size(); i++) {
float ratioPictureSizes = (float) pictureSizes.get(i).width / pictureSizes.get(i).height;
Log.i(TAG, "Picture Sizes: " + pictureSizes.get(i).width + "," + pictureSizes.get(i).height + ", " + ratioPictureSizes);
if (ratioPictureSizes / ratio < 1 + TOLERANCE || ratioPictureSizes / ratio < 1 - TOLERANCE) {
int thisWidth = pictureSizes.get(i).width;
if (thisWidth < lastWidth) continue;
else {
lastWidth = thisWidth;
candidate = i;
}
}
}
Log.i(TAG, "Size found: " + pictureSizes.get(candidate).width + "," + pictureSizes.get(candidate).height + ", " + (float) pictureSizes.get(candidate).width / pictureSizes.get(candidate).height);
mCamera.stopPreview();
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureSize(pictureSizes.get(candidate).width, pictureSizes.get(candidate).height);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
布局
<FrameLayout
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"
tools:context=".MainActivity"
android:background="#000000">
<FrameLayout
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
android:layout_gravity="center">
<com.example.raulgotor.phmeter2.DrawGrid
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/grid"
android:layout_centerInParent="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:id="@+id/linearLayout"
android:layout_alignParentBottom="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp">
<com.example.raulgotor.phmeter2.VerticalSeekBar android:id="@+id/vertical_Seekbar"
android:layout_width="50dp"
android:layout_height="110dp"
android:minHeight="110dip"
android:maxHeight="110dip"
android:indeterminate="false" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_centerInParent="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Foto"
android:id="@+id/shotButton"
android:layout_gravity="center|right" />
</LinearLayout>
</RelativeLayout>
</FrameLayout>
[1]: http://i.stack.imgur.com/70Ni5.jpg