2013-07-10 3 views
4

Я использую следующий код для выполнения обрезки изображения в android.Пользовательский обрезка изображения работает некорректно

Но я получаю неправильные результаты. Я получаю очень масштабирования изображения, я думаю, что есть что-то не так в моем коде

код:

package net.londatiga.android; 

import java.io.ByteArrayOutputStream; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.Point; 
import android.graphics.PointF; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.widget.ImageView; 

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(); 
    } 
} 

Образ, который я пытался сделать урожай

enter image description here

Ожидаемое изображение что есть в прямоугольной коробке, но я получаю очень увеличенное изображение.

приведенное изображение

enter image description here

Как я могу решить эту проблему, я попробовал, изменив код, но не нашли никаких результатов.

И еще одна проблема заключается в том, что с помощью этого прямоугольника я могу обрезать изображения только в фигурах Прямоугольник, есть ли возможность обрезать изображение в любой форме, которую я хочу.

Я наблюдал это в одном из приложений (версия журнала сканера документа), в котором пользователь может обрезать изображение в некоторых неправильных фигурах с использованием того же прямоугольника.

Как я могу достичь этого результата?

Пожалуйста, предложите

Благодаря

+0

сторонняя библиотека тоже есть. Вы можете использовать его, чтобы сэкономить время. –

+0

Не могли бы вы рассказать мне, что – user2376732

+0

Я застрял посередине, мне нужно было отправить все данные, такие как aspectx, aspecty и все остальные – user2376732

ответ

3

Я реализовал Android Crop Image библиотеку. Это очень полезно для меня. Он имеет следующие функции.

  1. Pinch зум, чтобы обрезать очень малую часть изображений
  2. прямоугольника, который изменяемый по изображению
  3. Эффективного результат Image Crop обратно к деятельности
  4. вращения объект

Редактировать

Для получения результата

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (data != null) if (data.getParcelableExtra("data") != null) 
    Bitmap bitmap = data.getParcelableExtra("data"); 
} 

Еще один Редактировать

Поиск private void handleFace(FaceDetector.Face f) метод в CropImage файле. Поместите следующий код внутри метода после HighlightView hv = new HighlightView(mImageView); этой строки.

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) { 
    mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

Также добавить код выше в private void makeDefault().

private void makeDefault(){ 
    HighlightView hv = new HighlightView(mImageView); 

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) { 
     mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
    } 
    //rest of code 
} 

По причине ускорения это необходимо. Если вы получите какую-либо ошибку в «GINGERBREAD» и «View.LAYOUT_TYPE_SOFTWARE», измените версию вашего API на 4.0 и выше.

Убедитесь, что регистрация активности, как показано ниже,

<activity 
     android:name="com.android.camera.CropImage" 
     android:hardwareAccelerated="false" /> 

Примечание Применение

Этот образец имеет грязный макет. Вам нужно прояснить себя. Это проект библиотеки, поэтому удалите «библиотека» из свойства проекта, чтобы запустить этот образец кода.

+0

Я получаю ошибки в классах Util, CropImage – user2376732

+0

Какая ошибка? –

+0

Класс MenuHelper не распознается, mLeft, mContext, переменные mRight не распознаются – user2376732

Смежные вопросы