2013-07-12 99 views
7

我正在製作應用程序我無法在最近3天內儘可能使用谷歌的一個問題。我在畫布上做了一個圓圈,並希望裁剪圖像的那部分並在縮放模式下顯示圖像。我的第一步就像在屏幕這裏: - enter image description here如何在畫布上裁剪選定區域的位圖?

在這我選擇area.here是我的代碼使用這個。

private float x, y; 
private boolean zooming = false; 
private Paint mPaint; 
private Matrix mmatrix; 
private Shader mShader; 
private Bitmap mBitmap; 
private List<Point> mpoints; 
private List<MyPoints> mpointlist; 
private Path mpath; 
private Canvas mcanvas; 
private Bitmap mresult_bitmap, resultingImage,finalbitmap; 
private Context mcontext; 
private boolean bfirstpoint = false; 
private Point mfirstpoint = null; 
private Point mlastpoint = null; 

public CircularZoomView(Context context) { 
    super(context); 
    mcontext = context; 
    mpath = new Path(); 
    mpoints = new ArrayList<Point>(); 
    setBackgroundResource(R.drawable.testing); 
    mPaint = new Paint(); 

    mresult_bitmap = BitmapFactory.decodeResource(getResources(), 
    R.drawable.testing); 

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0)); 
    mPaint.setStrokeWidth(5); 
    mPaint.setColor(Color.RED); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if (zooming && resultingImage!=null) { 
     zooming = false; 
     ShowImage(resultingImage); 
     canvas.drawBitmap(resultingImage,mmatrix, null); 
    } 
    boolean first = true; 

    for (int i = 0; i < mpoints.size(); i += 2) { 
     Point point = mpoints.get(i); 
     if (first) { 
      first = false; 
      mpath.moveTo(point.x, point.y); 
     } else if (i < mpoints.size() - 1) { 
      Point next = mpoints.get(i + 1); 
      mpath.quadTo(point.x, point.y, next.x, next.y); 
     } else { 
      mlastpoint = mpoints.get(i); 
      mpath.lineTo(point.x, point.y); 
     } 
    } 

    canvas.drawPath(mpath, mPaint); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    int action = event.getAction(); 

    x = event.getX(); 
    y = event.getY(); 

    Point point = new Point(); 
    point.x = (int) event.getX(); 
    point.y = (int) event.getY(); 

    if (bfirstpoint) { 
     if (comparepoint(mfirstpoint, point)) { 
      mpoints.add(mfirstpoint); 
      addCircleFromPath(mpath); 
     } else { 
      mpoints.add(point); 
     } 
    } else { 
     mpoints.add(point); 
    } 

    if (!(bfirstpoint)) { 
     mfirstpoint = point; 
     bfirstpoint = true; 
    } 

    invalidate(); 

    switch (action) { 
    case MotionEvent.ACTION_DOWN: 
    case MotionEvent.ACTION_MOVE: 

     zooming = false; 
     this.invalidate(); 
     break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_CANCEL: 
     zooming = true; 
     mlastpoint = point; 
      if (mpoints.size() > 12) { 
       if (!comparepoint(mfirstpoint, mlastpoint)) { 
        mpoints.add(mfirstpoint); 
        addCircleFromPath(mpath); 
       } 
      } 
     this.invalidate(); 
     break; 

    default: 
     break; 
    } 

    return true; 
} 


public Bitmap getCroppedBitmap(Bitmap bitmap) { 

    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), 
      bitmap.getHeight(), Config.ARGB_8888); 
    Canvas canvas = new Canvas(output); 

    final int color = 0xff424242; 
    final Paint paint = new Paint(); 
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 

    paint.setAntiAlias(true); 
    canvas.drawARGB(0, 0, 0, 0); 
    paint.setColor(color); 
    canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, 
      bitmap.getWidth()/2, paint); 
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
    canvas.drawBitmap(bitmap, rect, rect, paint); 
    return output; 
} 



void ShowImage(Bitmap mbitmap) { 
    Display display = ((MainActivity) mcontext).getWindowManager().getDefaultDisplay(); 
    int screenWidth = display.getWidth(); 
    float imageWidth = (float)mbitmap.getWidth(); 
    float imageHeight = (float)mbitmap.getHeight(); 
    float newHeight = imageHeight/(imageWidth/screenWidth); 
    float newWidth = screenWidth; 
    float scaleWidth = screenWidth/imageWidth; 
    float scaleHeight = newHeight/imageHeight; 
    SetImageMatrix(mbitmap,scaleWidth,scaleHeight); 

    } 

void SetImageMatrix(Bitmap image,float scaleWidth, float scaleHeight) { 
    mmatrix = new Matrix(); 
    mmatrix.setTranslate(40,40); 
    mmatrix.postScale(scaleWidth/2, scaleHeight/2); 
    /*image.setImageMatrix(mmatrix); 
    image.setScaleType(ScaleType.MATRIX); 
    image.invalidate();*/ 

    } 

private boolean comparepoint(Point first, Point current) { 
    int left_range_x = (int) (current.x - 3); 
    int left_range_y = (int) (current.y - 3); 

    int right_range_x = (int) (current.x + 3); 
    int right_range_y = (int) (current.y + 3); 


    if ((left_range_x < first.x && first.x < right_range_x) 
      && (left_range_y < first.y && first.y < right_range_y)) { 
     if (mpoints.size() < 10) { 
      return false; 
     } else { 
      return true; 
     } 
    } else { 
     return false; 
    } 

} 

private void addCircleFromPath(Path path){ 
    RectF bounds = new RectF(); 
    path.computeBounds(bounds, true); 
    int width = (int) (bounds.right-bounds.left); 
    int height = (int) (bounds.bottom-bounds.top); 
    if(width<20 && height<20){ 
     path.reset(); 
     return; 
    } 
    int radius ; 
    if(width>=height) 
     radius = Math.round(((width/2))); 
    else radius = Math.round((int) ((height/2))); 
    /*CircleTagObject circle = new CircleTagObject((int)bounds.left+width/2, (int)bounds.top+height/2, radius, crossBitmap, tagBitmap,circleArray.size(), 
      ImageEditorView.this); 
    circleArray.add(circle); 
    tagBallID = circleArray.size() - 1; 
    dragEnable = true;*/ 

    resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,0,0,200,200)); 
    mcanvas = new Canvas(resultingImage); 
    path.reset(); 
    resetView(); 
    invalidate(); 
} 

public void resetView() { 
    mpoints.clear(); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0)); 
    mPaint.setStrokeWidth(5); 
    mPaint.setColor(Color.RED); 
    invalidate(); 
} 

如果我創建硬編碼的位圖像上面那樣顯示好但不是所選部分的裁剪位圖。像這張圖片。 enter image description here

但是,當附加精確選定區域等作爲協調: -

resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,(int)bounds.left,(int)bounds.top,width,height)); 

然後例外occure: -

07-12 10:58:56.700: E/MessageQueue-JNI(12310): java.lang.IllegalArgumentException: y + height must be <= bitmap.height() 
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at android.graphics.Bitmap.createBitmap(Bitmap.java:565) 
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at android.graphics.Bitmap.createBitmap(Bitmap.java:530) 
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at com.intel.view.CircularZoomView.addCircleFromPath(CircularZoomView.java:237) 

我知道爲什麼這發生異常,但無法找到解決方案如何裁剪圖像的選定部分。提前感謝。

回答

6

我知道你的解決方案太晚了,但這可能有助於其他人Use of this code 幫助你從這個問題中走出來。

+0

它使用java或使用JNI工作嗎? –

+0

這是一個特定形狀的裁剪圖像的樣本。開發人員創建了一些算法和樣本形狀,如圓形或臉形。所以只有java代碼。沒有jni! –

+0

我的意思是,它使用JNI嗎?庫裏面有任何JNI代碼? –