关于如何裁剪从 Gallery 或 Camera 中获取的图像,有很多讨论。一个非常简单的,没有多少人喜欢,包括以下 fragment
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 617);
intent.putExtra("aspectY", 619);
(无论如何,该 fragment 是不完整的。继续......)
请注意我在代码 fragment 中如何使用两个大质数。我在这里希望限制最小裁剪尺寸。然而,617X619 似乎没有效果;这对我来说基本上意味着无论使用什么算法都具有类似于
的功能double scale = (double) aspectY/aspectX;
然后用于将 xDimen 与 yDimen 进行匹配。
但在我举手放弃之前,我注意到 instagram 已经成功地限制了 cropper 的最小尺寸。有谁知道我如何做到这一点?基本上,如果您使用 instagram,您会注意到您无法裁剪图像的“太小”部分。我该如何决定这些维度?
基本上就好像instagram在做
double scale = (double) aspectY/aspectX;
//....
if(someInputX > aspectX){
xDimen = someInputX;
yDimen = scale* xDimen;
}else{
//do not crop any further
}
我一直在查看一些裁剪库,看看是否可以弄清楚如何修复最小尺寸,但我似乎无法弄清楚。例如,我一直在研究 http://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html 链接的 git 项目。
最佳答案
Instagram 已经构建了自己的裁剪工具。如果您准备好构建裁剪工具,您可以控制任何东西。而且,构建一个简单的裁剪工具并不难。如果您对 MotionEvent
和 Bitmap
的工作原理有很好的理解,那么 1 小时就够了。
示例代码:取自 here
public class MainActivity extends Activity {
private ImageView imageView;
private ViewManager viewManager;
private Matrix matrix;
private int size;
private final int outputSize = 100;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
size = width < height ? width : height;
size -= 50;
imageView = (ImageView) findViewById(R.id.imageViewCrop);
imageView.getLayoutParams().width = size;
imageView.getLayoutParams().height = size;
viewManager = (ViewManager) imageView.getParent();
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
createZoomControls();
}
imageView.setOnTouchListener(new OnTouchListener() {
float initX;
float initY;
float midX;
float midY;
float scale;
float initDistance;
float currentDistance;
boolean isMultitouch = false;
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
initX = event.getX();
initY = event.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
isMultitouch = true;
initDistance = (float) Math.sqrt(Math.pow(
initX - event.getX(1), 2)
+ Math.pow(initY - event.getY(1), 2));
break;
case MotionEvent.ACTION_MOVE:
if (isMultitouch) {
matrix = imageView.getImageMatrix();
currentDistance = (float) Math.sqrt(Math.pow(initX
- event.getX(1), 2)
+ Math.pow(initY - event.getY(1), 2));
scale = 1 + 0.001f * (currentDistance - initDistance);
midX = 0.5f * (initX + event.getX(1));
midY = 0.5f * (initY + event.getY(1));
matrix.postScale(scale, scale, midX, midY);
imageView.setImageMatrix(matrix);
imageView.invalidate();
} else {
imageView.scrollBy((int) (initX - event.getX()),
(int) (initY - event.getY()));
initX = event.getX();
initY = event.getY();
}
break;
case MotionEvent.ACTION_UP:
isMultitouch = false;
break;
case MotionEvent.ACTION_POINTER_UP:
isMultitouch = false;
break;
}
return true;
}
});
}
public void createZoomControls() {
ZoomButtonsController zoomButtonsController = new ZoomButtonsController(
imageView);
zoomButtonsController.setVisible(true);
zoomButtonsController.setAutoDismissed(false);
zoomButtonsController.setOnZoomListener(new OnZoomListener() {
public void onZoom(boolean zoomIn) {
matrix = imageView.getImageMatrix();
if (zoomIn) {
matrix.postScale(1.05f, 1.05f, 0.5f * size, 0.5f * size);
imageView.setImageMatrix(matrix);
} else {
matrix.postScale(0.95f, 0.95f, 0.5f * size, 0.5f * size);
imageView.setImageMatrix(matrix);
}
imageView.invalidate();
}
public void onVisibilityChanged(boolean visible) {
}
});
RelativeLayout.LayoutParams zoomLayoutParams = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
zoomLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
zoomLayoutParams.addRule(RelativeLayout.BELOW, R.id.imageViewCrop);
viewManager.addView(zoomButtonsController.getContainer(),
zoomLayoutParams);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
Toast.makeText(this, R.string.info, 5).show();
return super.onMenuItemSelected(featureId, item);
}
public void buttonPickClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (resultCode) {
case RESULT_OK:
Uri targetUri = data.getData();
imageView.setScaleType(ScaleType.CENTER_INSIDE);
imageView.scrollTo(0, 0);
imageView.setImageURI(targetUri);
imageView.setScaleType(ScaleType.MATRIX);
break;
}
}
public void buttonCropClick(View view) throws IOException {
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache(true);
File imageFile = new File(Environment.getExternalStorageDirectory(),
"Pictures/" + UUID.randomUUID().toString() + ".jpg");
FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
Bitmap.createScaledBitmap(imageView.getDrawingCache(true), outputSize,
outputSize, false).compress(CompressFormat.JPEG, 100,
fileOutputStream);
fileOutputStream.close();
imageView.setDrawingCacheEnabled(false);
}
}
处理高分辨率图像时要小心 http://developer.android.com/training/displaying-bitmaps/index.html
关于android - 如何限制android中图像的最小可裁剪尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24024472/