关于如何裁剪从图库或相机拍摄的图像,有很多话题。一个非常简单的,包括以下代码片段
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 617);
intent.putExtra("aspectY", 619);
(无论如何,该片段应该是不完整的。继续......)
请注意我在代码片段中如何使用两个大素数。我在这里希望限制最小的作物尺寸。然而,617X619似乎没有效果;对我来说,基本上意味着所使用的算法具有类似于
的功能double scale = (double) aspectY/aspectX;
然后用于将xDimen与yDimen匹配。
但是在把手放在空中然后放弃之前,我注意到instagram已经成功地限制了裁剪器的最小尺寸。有谁知道我怎么做到这一点?基本上如果你使用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项目答案 0 :(得分:2)
您是否愿意使用第三方库?如果是这样,你可以使用这个并更改它以限制最小矩形大小(我不相信它默认允许这样做但是如果你真的想要将它添加到代码中很容易)。
答案 1 :(得分:1)
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