studio recortar programacion profesionales por fotos editar contorno como celular android crop

android - programacion - recortar fotos



Recorte personalizado de imágenes de Android (3)

Solo quiero compartir este pedazo de código que escribí. Intenté buscar una actividad de recorte personalizada, pero la mayoría de ellos lleva al valor predeterminado "com.android.camera.action.CROP" a pesar de la pregunta de recorte personalizado o actividad de recorte a mano alzada. De todos modos, acabo de hacer una para mí, y espero que les ayude a ustedes.

public class CropView extends ImageView { Paint paint = new Paint(); private int initial_size = 300; private static Point leftTop, rightBottom, center, previous; private static final int DRAG= 0; private static final int LEFT= 1; private static final int TOP= 2; private static final int RIGHT= 3; private static final int BOTTOM= 4; private int imageScaledWidth,imageScaledHeight; // Adding parent class constructors public CropView(Context context) { super(context); initCropView(); } public CropView(Context context, AttributeSet attrs) { super(context, attrs, 0); initCropView(); } public CropView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initCropView(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(leftTop.equals(0, 0)) resetPoints(); canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint); } @Override public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: previous.set((int)event.getX(), (int)event.getY()); break; case MotionEvent.ACTION_MOVE: if(isActionInsideRectangle(event.getX(), event.getY())) { adjustRectangle((int)event.getX(), (int)event.getY()); invalidate(); // redraw rectangle previous.set((int)event.getX(), (int)event.getY()); } break; case MotionEvent.ACTION_UP: previous = new Point(); break; } return true; } private void initCropView() { paint.setColor(Color.YELLOW); paint.setStyle(Style.STROKE); paint.setStrokeWidth(5); leftTop = new Point(); rightBottom = new Point(); center = new Point(); previous = new Point(); } public void resetPoints() { center.set(getWidth()/2, getHeight()/2); leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2); rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size); } private static boolean isActionInsideRectangle(float x, float y) { int buffer = 10; return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false; } private boolean isInImageRange(PointF point) { // Get image matrix values and place them in an array float[] f = new float[9]; getImageMatrix().getValues(f); // Calculate the scaled dimensions imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]); imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]); return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false; } private void adjustRectangle(int x, int y) { int movement; switch(getAffectedSide(x,y)) { case LEFT: movement = x-leftTop.x; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) leftTop.set(leftTop.x+movement,leftTop.y+movement); break; case TOP: movement = y-leftTop.y; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) leftTop.set(leftTop.x+movement,leftTop.y+movement); break; case RIGHT: movement = x-rightBottom.x; if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); break; case BOTTOM: movement = y-rightBottom.y; if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); break; case DRAG: movement = x-previous.x; int movementY = y-previous.y; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) { leftTop.set(leftTop.x+movement,leftTop.y+movementY); rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY); } break; } } private static int getAffectedSide(float x, float y) { int buffer = 10; if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer)) return LEFT; else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer)) return TOP; else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer)) return RIGHT; else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer)) return BOTTOM; else return DRAG; } public byte[] getCroppedImage() { BitmapDrawable drawable = (BitmapDrawable)getDrawable(); float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2); float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2); Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y); ByteArrayOutputStream stream = new ByteArrayOutputStream(); cropped.compress(Bitmap.CompressFormat.PNG, 100, stream); return stream.toByteArray(); } }

Lo que hice fue extender el ImageView y agregar poderes de recorte. Es muy facil de usar. Una vez que la clase está guardada, solo úsala en el diseño como este.

<"your package name".CropView android:id="@+id/image_preview" android:layout_width="fill_parent" android:layout_height="match_parent" />

¡Eso es! ¡Espero eso ayude! Si tiene algún problema, no dude en preguntar :)


Deberías intentarlo:

@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.crop_layout); myCropView = new CropView(this); Uri imageUri = getIntent().getExtras().getParcelable("path"); b = (BitmapDrawable) BitmapDrawable.createFromPath(imageUri.getPath()); myCropView.setImageURI(imageUri); }

(Tomado de una edición a su pregunta.)


Encontré una biblioteca que admite esto: SimpleCropView de https://android-arsenal.com/details/1/2366 . En general, no lo recomendaría, su rendimiento está lejos de las aplicaciones nativas de recorte de Android.

He intentado usarlo, y mis pensamientos son:

  • Realmente sencillo de implementar en su aplicación, me llevó aproximadamente 5 minutos obtener la funcionalidad de recorte y rotación que funciona con mi aplicación existente

  • El cambio de tamaño del área de cultivo es dolorosamente lento, no me gustaría que mi usuario lo vea.

ACTUALIZACIÓN: De hecho, he encontrado una solución realmente buena como jdamcd / android-crop en Github: https://github.com/jdamcd/android-crop Resumen:

  • Muy simple de usar en tu aplicación

  • Rápido, ya que utiliza el código de la aplicación de galería nativa.

  • Personalizable, si quieres pasar un rato jugando con él. De forma predeterminada, le proporciona una Actividad en la que realiza el recorte. Si desea integrarlo en su propia actividad, tomará un poco más de tiempo. (Para mi proyecto me hubiera gustado integrarlo, y lo haré en el futuro, pero por ahora una actividad separada es suficiente).

Espero que esto proporcione una idea!


gracias thehippo ... pero he resuelto encontrar la vista por el diseño

Uri imageUri = getIntent().getExtras().getParcelable("path"); b = (BitmapDrawable) BitmapDrawable.createFromPath(getRealPathFromURI(imageUri)); myCropView = (CropView) findViewById(R.id.image_preview); myCropView.setBackground(b);

Pero ahora no puedo manejar el evento táctil. El rectángulo se queda quieto incluso si toco la pantalla ...

EDIT: ok, he hecho que funcione. Pero ahora, el rectángulo se mueve solo dentro de un área más pequeña, no en toda la imagen. Supongo que hay algo mal aquí.

private boolean isInImageRange(PointF point) { // Get image matrix values and place them in an array float[] f = new float[9]; getImageMatrix().getValues(f); // Calculate the scaled dimensions imageScaledWidth = Math.round(getBackground().getIntrinsicWidth() * f[Matrix.MSCALE_X]); imageScaledHeight = Math.round(getBackground().getIntrinsicHeight() * f[Matrix.MSCALE_Y]); return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false; }

He hecho un pequeño cambio para hacer funcionar el código: getBackground () en lugar de getDrawable

EDITAR 2: OK lo tengo, estaba haciendo esto de manera incorrecta. Tu código es bueno. Para configurar la imagen, estaba usando view.seBackground () ... en lugar de view.setImageDrawable (). Ahora todo funciona. Tal vez solo compruebe si es posible crear un área más grande que dispare la escala del rectángulo