// Rotates the bitmap by the specified degree. // If a new bitmap is created, the original bitmap is recycled. public static Bitmap rotateAndCrop(Bitmap b, int degrees, Rect crop) { if (b == null) return b; Bitmap b2 = null; int scale = Util.scalePow2(b.getHeight(), b.getWidth()); if (scale != 1 && crop != null) { crop.left *= scale; crop.right *= scale; crop.bottom *= scale; crop.top *= scale; } try { if (degrees != 0) { Matrix m = new Matrix(); m.setRotate(degrees, 0, 0); RectF r_rot = new RectF(0, 0, b.getWidth(), b.getHeight()); m.mapRect(r_rot); m.postTranslate(-r_rot.left, -r_rot.top); // r_rot.set(0,0,b.getWidth(),b.getHeight()); // m.mapRect(r_rot); // Log.d(TAG, "rotated bitmap = "+r_rot.toString()); if (crop == null) b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); else { Matrix minv = new Matrix(); m.invert(minv); // minv.postScale(scale, scale); RectF r = new RectF(); r.set(crop); minv.mapRect(r); Log.d(TAG, "crop = " + crop.toString()); r.round(crop); Log.d(TAG, "bitmap " + b.getDensity() + " " + b.getWidth() + " x " + b.getHeight()); Log.d(TAG, "inv rotated crop = " + crop.toString()); b2 = Bitmap.createBitmap(b, crop.left, crop.top, crop.width(), crop.height(), m, true); } } else { if (crop != null) { Log.d(TAG, "crop = " + crop.toString()); Log.d(TAG, "bitmap " + b.getDensity() + " " + b.getWidth() + " x " + b.getHeight()); b2 = Bitmap.createBitmap(b, crop.left, crop.top, crop.width(), crop.height()); // b2 = Bitmap.createBitmap(b, scale*crop.left, scale*crop.top, // scale*crop.width(), scale*crop.height()); } else b2 = b; } } catch (OutOfMemoryError ex) { // We have no memory to rotate. Return the original bitmap. b2 = b; } Assert.assertNotNull(b2); if (b == b2) { return b; } else { Log.d(TAG, "b != b2, recycling b"); b.recycle(); return b2; } }
/** * Register a HotSpot that should fire a listener when a touch event occurs that intersects the * Region defined by the HotSpot. * * <p>The HotSpot virtually moves and scales with the TileView. * * @param positions (List<double[]>) List of paired doubles that represents the region. * @return HotSpot the hotspot created with this method. */ public HotSpot addHotSpot(List<double[]> positions, HotSpot.HotSpotTapListener listener) { Path path = mCoordinateTranslater.pathFromPositions(positions, true); RectF bounds = new RectF(); path.computeBounds(bounds, true); Rect rect = new Rect(); bounds.round(rect); Region clip = new Region(rect); HotSpot hotSpot = new HotSpot(); hotSpot.setPath(path, clip); hotSpot.setHotSpotTapListener(listener); return addHotSpot(hotSpot); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (angleChanged) { final RectF layoutRect = tempRectF1; final RectF layoutRectRotated = tempRectF2; layoutRect.set(0, 0, r - l, b - t); rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY()); rotateMatrix.mapRect(layoutRectRotated, layoutRect); layoutRectRotated.round(viewRectRotated); angleChanged = false; } final View view = getView(); if (view != null) { view.layout( viewRectRotated.left, viewRectRotated.top, viewRectRotated.right, viewRectRotated.bottom); } }
/** @return the bounds where the image was drawn. */ public Rect getBitmapBounds() { updateDstRectF(); Rect rect = new Rect(); mDstRectF.round(rect); return rect; }