我以前做过一些几乎与此类似的事情。因此,您需要按照以下方法进行操作:首先需要定位相对于视图矩形的点,例如,如果要放置帽子,首先要放置基于CameraView的针尖头和帽子的相对矩形,然后将帽子放在该坐标上。这是容易的部分。困难的部分是保存图像。为此,您需要保存CameraView的宽度和长度及其上的贴纸及其在CameraView上的位置。然后,捕获图像并获得位图/可绘制对象。您最有可能获得与CameraView不同的打印位图大小,因此您需要根据此位图与CameraView的w / h重新计算此位图上的贴纸坐标,并在新坐标上合并贴纸,然后保存它。这并不容易,但就像我所做的那样是可能的。
这是我的代码(在我的情况下,贴纸被放置在图片的中心):
/**
* Created by Mohammad Erfan Molaei on 9/26/16.
*/
public class CaptureActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback {
private static final String TAG = "CaptureActivity";
private FloatingActionButton takePicture;
private int mCurrentFlash;
private CameraView mCameraView;
private int cameraWidth;
private int cameraHeight;
private int drawableWidth;
private int drawableHeight;
private Handler mBackgroundHandler;
private boolean selectedBrand;
@Override
public void setTheme(int resId) {
selectedBrand = getSharedPreferences(getString(R.string.brand_pref), MODE_PRIVATE)
.getBoolean(getString(R.string.selected_brand), true);
super.setTheme(selectedBrand ? R.style.AppTheme_CaptureTheme : R.style.AppTheme_CaptureTheme2);
}
private String itemID = null;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture:
if (mCameraView != null) {
mCameraView.takePicture();
takePicture.setEnabled(false);
}
break;
case R.id.scale_up_btn:
scaleUpImage();
break;
case R.id.scale_down_btn:
scaleDownImage();
break;
}
}
};
private void scaleUpImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
/*Log.e(TAG, "scaleDownImage: oldWidth: " + imageView.getLayoutParams().width +
", oldHeight: " + imageView.getLayoutParams().height);
Log.e(TAG, "scaleDownImage: newWidth2B: " + (imageView.getLayoutParams().width * 1.1f) +
", newHeight2B: " + ((1.1f * imageView.getLayoutParams().width) *
imageView.getLayoutParams().height /
imageView.getLayoutParams().width));
Log.e(TAG, "cameraWidth: " + mCameraView.getLayoutParams().width );
sdasd*/
if (imageView.getWidth() * 1.1f > mCameraView.getWidth() ||
((1.1f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth()) > mCameraView.getHeight())
return;
imageView.getLayoutParams().height = (int) ((1.1f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth());
imageView.getLayoutParams().width = (int) (imageView.getWidth() * 1.1f);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
}
}
private void scaleDownImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
if (imageView.getWidth() * 0.9f > mCameraView.getWidth() ||
((0.9f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth()) > mCameraView.getHeight())
return;
imageView.getLayoutParams().height = (int) ((0.9f * imageView.getWidth()) *
imageView.getHeight() /
imageView.getWidth());
imageView.getLayoutParams().width = (int) (imageView.getWidth() * 0.9f);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
}
}
private void rotateImage() {
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
/*Drawable mDrawable = imageView.getDrawable();
int mDrawableWidth = mDrawable.getBounds().width();
int mDrawableHeight = mDrawable.getBounds().height();*/
int newWidth = imageView.getHeight();
int newHeight = imageView.getWidth();
float scaleFactor = 1;
/*Log.e(TAG, "rotateImage: prevWidth: " + newHeight + ", prevHeight: " + newWidth);
Log.e(TAG, "rotateImage: cameraWidth: " + mCameraView.getWidth() );*/
if (newWidth > mCameraView.getWidth() ) {
scaleFactor = (float)newWidth / (float)mCameraView.getWidth();
newWidth = mCameraView.getWidth();
newHeight *= scaleFactor;
} else if (newHeight > mCameraView.getHeight() ) {
scaleFactor = (float)newHeight / (float)mCameraView.getHeight();
newHeight = mCameraView.getHeight();
newWidth *= scaleFactor;
}
Log.e(TAG, "rotateImage: scaleFactor: " + scaleFactor);
imageView.setRotation(imageView.getRotation() + 90);
imageView.getLayoutParams().height = newHeight;
imageView.getLayoutParams().width = newWidth;
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.requestLayout();
/*drawableWidth = dp2px(imageView.getWidth());
drawableHeight = dp2px(imageView.getHeight());*/
//imageView.setImageDrawable(getRotatedDrawable(imageView));
/*Bitmap bitmapOrg = drawableToBitmap(imageView.getDrawable());
// createa matrix for the manipulation
Matrix matrix = imageView.getImageMatrix();
int width = bitmapOrg.getWidth();
int height = bitmapOrg.getHeight();
// rotate the Bitmap
matrix.postRotate(90);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(getResources(), resizedBitmap);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);*/
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture);
mCameraView = (CameraView) findViewById(R.id.camera);
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
takePicture = (FloatingActionButton) findViewById(R.id.take_picture);
if (takePicture != null) {
takePicture.setOnClickListener(mOnClickListener);
}
/*if (selectedBrand) {
assert takePicture != null;
takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent));
findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary));
} else {
assert takePicture != null;
takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent2));
findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary2));
}*/
findViewById(R.id.scale_up_btn).setOnClickListener(mOnClickListener);
findViewById(R.id.scale_down_btn).setOnClickListener(mOnClickListener);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras != null) {
itemID = extras.getString("id", null);
}
} else {
itemID = (String) savedInstanceState.getSerializable("id");
}
if( itemID != null ) {
new AsyncImageLoader().execute(itemID);
} else {
this.finish();
return;
}
ViewTreeObserver viewTreeObserver = mCameraView.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
/*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mCameraView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mCameraView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}*/
cameraWidth = dp2px(mCameraView.getWidth());
cameraHeight = dp2px(mCameraView.getHeight());
Log.e("camB4Action", "" + cameraWidth + ", " + cameraHeight);
}
});
}
}
@Override
protected void onResume() {
super.onResume();
mCameraView.start();
}
@Override
protected void onPause() {
mCameraView.stop();
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
}
private Drawable getFlippedDrawable(final Drawable d) {
final Drawable[] arD = { d };
return new LayerDrawable(arD) {
@Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.scale(-1, 1, d.getBounds().width() / 2, d.getBounds().height() / 2);
super.draw(canvas);
canvas.restore();
}
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.camera, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.switch_flash:
if (mCameraView != null) {
mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
item.setTitle(FLASH_TITLES[mCurrentFlash]);
item.setIcon(FLASH_ICONS[mCurrentFlash]);
mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
}
break;
case R.id.switch_camera:
if (mCameraView != null) {
int facing = mCameraView.getFacing();
mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
CameraView.FACING_BACK : CameraView.FACING_FRONT);
}
break;
case R.id.mirror_image:
if (mCameraView != null) {
SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
imageView.setImageDrawable(getFlippedDrawable(imageView.getDrawable()));
imageView.requestLayout();
}
break;
case R.id.rotate_image:
if (mCameraView != null) {
rotateImage();
}
break;
}
return false;
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
public static Bitmap scaleBitmap(Bitmap bitmap, int wantedWidth, int wantedHeight, float rotation) {
Log.e(TAG, "scaleBitmap: bitmapWidth: " + bitmap.getWidth() + ", bitmapHeight: " + bitmap.getHeight() );
Log.e(TAG, "scaleBitmap: wantedWidth: " +
((rotation % 180 == 90) ? wantedHeight : wantedWidth) +
", wantedHeight: " + ((rotation % 180 == 90) ? wantedWidth : wantedHeight) );
Bitmap output = Bitmap.createBitmap(
(rotation % 180 == 90) ? wantedHeight : wantedWidth,
(rotation % 180 == 90) ? wantedWidth : wantedHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Matrix m = new Matrix();
m.setScale((float)
((rotation % 180 == 90) ? wantedHeight : wantedWidth) / bitmap.getWidth(),
(float) ((rotation % 180 == 90) ? wantedWidth : wantedHeight) / bitmap.getHeight());
canvas.drawBitmap(bitmap, m, new Paint());
return output;
/*Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()),
new RectF(0, 0, (rotation % 180 == 90) ? wantedHeight : wantedWidth,
(rotation % 180 == 90) ? wantedWidth : wantedHeight), Matrix.ScaleToFit.CENTER);
return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);*/
}
private CameraView.Callback mCallback
= new CameraView.Callback() {
ProgressiveToast progressiveToast;
@Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
@Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
@Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
/*TastyToast.makeText(cameraView.getContext(), getString(R.string.pic_being_saved),
TastyToast.LENGTH_LONG, TastyToast.INFO);*/
progressiveToast = ProgressiveToast.getInstance();
progressiveToast.show(CaptureActivity.this, getString(R.string.in_action_be_patient), -1);
getBackgroundHandler().post(new Runnable() {
@Override
public void run() {
mCameraView.stop();
// This demo app saves the taken picture to a constant file.
// $ adb pull /sdcard/Android/data/com.google.android.cameraview.demo/files/Pictures/picture.jpg
SizeAwareImageView imageView = ((SizeAwareImageView) mCameraView.findViewById(R.id.mImageView));
Bitmap imageBitmap =
drawableToBitmap(imageView.getDrawable());
Matrix matrix = new Matrix();
float rotation = mCameraView.findViewById(R.id.mImageView).getRotation();
matrix.postRotate(rotation);
//matrix.postScale(drawableWidth, drawableHeight);
/*
matrix.setScale((float)
((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getWidth(),
(float) ((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getHeight());*/
Log.e(TAG, "rotation: " + rotation);
imageBitmap = Bitmap.createBitmap(imageBitmap , 0, 0,
imageBitmap.getWidth(), imageBitmap.getHeight(), matrix, true);
imageBitmap = scaleBitmap(imageBitmap, drawableWidth, drawableHeight, rotation);
Bitmap cameraBmp = BitmapFactory.decodeByteArray(data, 0, data.length);
cameraBmp = fixOrientation(cameraBmp);
File dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + getString(R.string.gallery_folder_name) +
(selectedBrand ? getString(R.string.ibr_eng) :
getString(R.string.tiyaco_eng)));
dir.mkdirs();
File file = new File(dir.getAbsolutePath() ,
Long.toString(Calendar.getInstance().getTimeInMillis()) + ".jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
OutputStream os = null;
InputStream is = overlayBitmapToCenter(cameraBmp, imageBitmap, rotation);
byte[] buffer = new byte[10 * 1024];
int n = 0;
try {
os = new FileOutputStream(file);
while (-1 != (n = is.read(buffer))) {
os.write(buffer, 0, n);
}
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mCameraView != null)
try {
mCameraView.start();
} catch (Exception ignored){}
if (takePicture != null) {
takePicture.setEnabled(true);
}
progressiveToast.dismiss();
TastyToast.makeText(getApplicationContext(), getString(R.string.picture_taken),
TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
}
});
}
}
}
});
}
};
public Bitmap fixOrientation(Bitmap mBitmap) {
if (mBitmap.getWidth() > mBitmap.getHeight()) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
return Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
}
return mBitmap;
}
private int dp2px(int dp) {
return (int)((dp * getResources().getDisplayMetrics().density) + 0.5);
}
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public ByteArrayInputStream overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2, float rotation) {
float alpha = (float)cameraWidth / (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth);
float beta = (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth) /
(float)((rotation % 180 == 90) ? drawableWidth : drawableHeight);
int bitmap1Width = bitmap1.getWidth();
int bitmap1Height = bitmap1.getHeight();
Bitmap scaledImg = Bitmap.createScaledBitmap(bitmap2, (int)((float)bitmap1Width / alpha),
(int)(((float)bitmap1Width / alpha) / beta), false);
int bitmap2Width = scaledImg.getWidth();
int bitmap2Height = scaledImg.getHeight();
/*Log.e("cam", "" + bitmap1Width + ", " + bitmap1Height );
Log.e("img", "" + bitmap2Width + ", " + bitmap2Height );
Log.e("alpha", "" + alpha );
Log.e("beta", "" + beta );*/
float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);
Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
Canvas canvas = new Canvas(overlayBitmap);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(scaledImg, marginLeft, marginTop, null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
overlayBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return new ByteArrayInputStream(stream.toByteArray());
}
private class AsyncImageLoader extends AsyncTask<String, Void, BitmapDrawable>{
private Realm realm;
private ProductModel product;
@Override
protected BitmapDrawable doInBackground(String... itemIds) {
realm = Realm.getDefaultInstance();
product = realm.where(ProductModel.class)
.equalTo("isIbr", selectedBrand)
.equalTo("id", itemIds[0])
.findFirst();
byte[] image = product.getImage();
product = null;
realm.close();
BitmapDrawable mDrawable = new BitmapDrawable(getResources(), BitmapFactory
.decodeByteArray(image, 0, image.length));
int mDrawableHeight = mDrawable.getIntrinsicHeight();
int mDrawableWidth = mDrawable.getIntrinsicWidth();
int valueInPixels = (int) getResources().getDimension(R.dimen.video_view_dimen);
mDrawable.setBounds(0, 0, valueInPixels, valueInPixels * mDrawableHeight / mDrawableWidth);
return mDrawable;
}
@Override
protected void onPostExecute(BitmapDrawable drawable) {
super.onPostExecute(drawable);
LayoutInflater vi = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View v = vi.inflate(R.layout.imageview_product, null);
((SizeAwareImageView)v).setImageDrawable(drawable);
ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e(TAG, "onGlobalLayout: updating sizes for drawable");
float[] sizez = ((SizeAwareImageView) v).getImageWidthAndHeight();
/*if (v.getRotation() == 90 || v.getRotation() == 270) {
drawableWidth = dp2px(sizez[1]);
drawableHeight = dp2px(sizez[0]);
} else {
drawableWidth = dp2px(sizez[0]);
drawableHeight = dp2px(sizez[1]);
}*/
drawableWidth = dp2px((int) sizez[0]);
drawableHeight = dp2px((int) sizez[1]);
/*Log.e("picB4Action", "" + drawableWidth + ", " + drawableHeight);*/
}
});
}
int px = (int) (getResources().getDimension(R.dimen.video_view_dimen)/* /
getResources().getDisplayMetrics().density*/);
mCameraView.addView(v, new FrameLayout.LayoutParams(px, px, Gravity.CENTER));
}
}
}
大小图像查看.java :
public class SizeAwareImageView extends ImageView {
public SizeAwareImageView(Context context) {
super(context);
}
public SizeAwareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SizeAwareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SizeAwareImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
}
public float[] getMatrixValues() {
float[] f = new float[9];
getImageMatrix().getValues(f);
return f;
}
public float[] getImageWidthAndHeight() {
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
//Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
return new float[] {actW, actH, scaleX, scaleY};
}
}