Crop d'image Android personnalisée
je veux juste partager ce morceau de code que j'ai écrit. J'ai essayé de chercher pour une mesure de la récolte de l'activité, mais la plupart d'entre eux conduit à la valeur par défaut "com.android.de la caméra.d'action.CULTURE" en dépit de la question de la coutume de la récolte, ou à main levée à la récolte de l'activité. De toute façon, je n'ai fait qu'un pour moi, et j'espère qu'il va vous aider les gars.
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();
}
}
Ce que j'ai fait, j'ai prolongé l'ImageView et ajouté culture de pouvoirs. Il est assez facile à utiliser. Une fois que la classe est enregistré, il suffit d'utiliser dans le layout de ce genre.
<"your package name".CropView
android:id="@+id/image_preview"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
C'est tout! Espérons que cela aide! Si vous rencontrez un quelconque problème, n'hésitez pas à demander 🙂
source d'informationauteur Seph Remotigue | 2013-04-24
Vous devez vous connecter pour publier un commentaire.
Vous devriez essayer:
(Prises à partir d'une modification à votre question.)
grâce thehippo... mais j'ai résolu de trouver le point de vue par la mise en page
mais maintenant je ne peux pas gérer l'événement tactile. Le rectangle de rester immobile, même si je touche l'écran...
EDIT: ok, j'ai fait ça fonctionne. Mais maintenant, le rectangle se déplacer qu'à l'intérieur d'une zone plus petite, pas dans l'ensemble de l'image. Je suppose qu'il ya quelque chose de mal ici
j'ai fait un peu de changement à faire le travail sur le code: getBackground() au lieu de getDrawable
EDIT 2: OK, ive a obtenu, j'ai fait ça dans le mauvais sens. Vous êtes le code est bon. Pour définir l'image que j'ai été en utilisant la vue.seBackground()...au lieu de la vue.setImageDrawable(). Maintenant tout fonctionne. Peut-être que je vais vérifier si c'est possible de créer une zone plus vaste que les feux de la mise à l'échelle du rectangle
J'ai trouvé une bibliothèque qui prend en charge ce: SimpleCropView de https://android-arsenal.com/details/1/2366. En général, je ne le recommanderais pas, sa performance est loin d'être le natif android recadrage apps.
J'ai essayé de l'utiliser, et mes pensées sont:
Vraiment simple à mettre en œuvre dans votre application, m'a pris environ 5 minutes pour obtenir des cultures de rotation et de la fonctionnalité de travail avec mon app
Le re-dimensionnement de la zone de recadrage est très lent, je ne voudrais pas que mon utilisateur pour voir.
Mise à JOUR:
En fait, j'ai trouvé une très bonne solution que jdamcd/android-récolte sur Github: https://github.com/jdamcd/android-crop
Résumé:
Très simple à utiliser dans votre application
Rapide car il utilise le code de native application galerie
Personnalisable, si vous voulez passer un peu de temps à jouer avec elle. Par défaut, il vous offre une Activité où vous ne le recadrage. Si vous souhaitez l'intégrer à votre propre activité, il va prendre un peu de mor temps. (Pour mon projet j'aurais aimé intégrer, et il le fera dans l'avenir, mais pour l'instant, une activité distincte est assez).
Espérons que cela donne une idée!