Java Code Examples for android.graphics.Matrix.setRotate()

The following are Jave code examples for showing how to use setRotate() of the android.graphics.Matrix class. You can vote up the examples you like. Your votes will be used in our system to get more good examples.
Example 1
Project: CameraKitView   File: Camera2Fragment.java   Source Code and License Vote up 7 votes
void setManualFocusAt(int x, int y) {
    int mDisplayOrientation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
    float points[] = new float[2];
    points[0] = (float) x / mTextureView.getWidth();
    points[1] = (float) y / mTextureView.getHeight();
    Matrix rotationMatrix = new Matrix();
    rotationMatrix.setRotate(mDisplayOrientation, 0.5f, 0.5f);
    rotationMatrix.mapPoints(points);
    if (mPreviewRequestBuilder != null) {
        mIsManualFocusing = true;
        updateManualFocus(points[0], points[1]);
        if (mPreviewSession != null) {
            try {
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CaptureRequest.CONTROL_AF_TRIGGER_START);
                mPreviewSession.capture(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
                mPreviewSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                    null, mBackgroundHandler);
            } catch (CameraAccessException | IllegalStateException e) {
                Log.e(TAG, "Failed to set manual focus.", e);
            }
        }
        resumeAutoFocusAfterManualFocus();
    }
}
 
Example 2
Project: GitHub   File: ImageDecoder.java   Source Code and License Vote up 6 votes
/**
 * 旋转图片
 *
 * @param source
 * @param angle
 * @param recycleSource
 * @return
 */
public static Bitmap rotate(Bitmap source, int angle, boolean recycleSource) {
    Bitmap result = null;

    if (angle != 0) {

        Matrix m = new Matrix();
        m.setRotate(angle);
        try {
            result = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), m, true);
        } catch (Throwable ex) {
            LogUtil.e(ex.getMessage(), ex);
        }
    }

    if (result != null) {
        if (recycleSource && result != source) {
            source.recycle();
            source = null;
        }
    } else {
        result = source;
    }
    return result;
}
 
Example 3
Project: siiMobilityAppKit   File: MultiImageChooserActivity.java   Source Code and License Vote up 6 votes
private Bitmap tryToGetBitmap(File file, BitmapFactory.Options options, int rotate, boolean shouldScale) throws IOException, OutOfMemoryError {
    Bitmap bmp;
    if (options == null) {
        bmp = BitmapFactory.decodeFile(file.getAbsolutePath());
    } else {
        bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
    }
    if (bmp == null) {
        throw new IOException("The image file could not be opened.");
    }
    if (options != null && shouldScale) {
        float scale = calculateScale(options.outWidth, options.outHeight);
        bmp = this.getResizedBitmap(bmp, scale);
    }
    if (rotate != 0) {
        Matrix matrix = new Matrix();
        matrix.setRotate(rotate);
        bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
    }
    return bmp;
}
 
Example 4
Project: CSVideo   File: CsVideo.java   Source Code and License Vote up 6 votes
private void savePhoto(byte[] data) throws IOException {
    imageFile = getFileForImg();
    if(imageFile != null){
        int rotation;
        if(cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            rotation = 90;
        }else if(cameraId == Camera.CameraInfo.CAMERA_FACING_FRONT){
            rotation = -90;
        }else{
            Toast.makeText(CsVideo.this,"发生未知错误!",Toast.LENGTH_SHORT).show();
            startRecordingView.setEnable(true);
            return;
        }
        Bitmap bm0 = BitmapFactory.decodeByteArray(data, 0, data.length);
        Matrix m = new Matrix();
        m.setRotate(rotation,(float) bm0.getWidth() / 2, (float) bm0.getHeight() / 2);
        final Bitmap bm = Bitmap.createBitmap(bm0, 0, 0, bm0.getWidth(), bm0.getHeight(), m, true);
        bm.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(imageFile));
        startUcrop("file://"+imageFile.getPath());
    }else{
        Toast.makeText(CsVideo.this,"发生未知错误!",Toast.LENGTH_SHORT).show();
        startRecordingView.setEnable(true);
    }

}
 
Example 5
Project: localcloud_fe   File: CameraLauncher.java   Source Code and License Vote up 6 votes
/**
 * Figure out if the bitmap should be rotated. For instance if the picture was taken in
 * portrait mode
 *
 * @param rotate
 * @param bitmap
 * @return rotated bitmap
 */
private Bitmap getRotatedBitmap(int rotate, Bitmap bitmap, ExifHelper exif) {
    Matrix matrix = new Matrix();
    if (rotate == 180) {
        matrix.setRotate(rotate);
    } else {
        matrix.setRotate(rotate, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
    }

    try
    {
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        exif.resetOrientation();
    }
    catch (OutOfMemoryError oom)
    {
        // You can run out of memory if the image is very large:
        // http://simonmacdonald.blogspot.ca/2012/07/change-to-camera-code-in-phonegap-190.html
        // If this happens, simply do not rotate the image and return it unmodified.
        // If you do not catch the OutOfMemoryError, the Android app crashes.
    }

    return bitmap;
}
 
Example 6
Project: youkes_browser   File: HelpUtils.java   Source Code and License Vote up 6 votes
/**
 *
 * @param src
 * @param degree
 * @return
 */
public static Bitmap degreeBitmap(Bitmap src , float degree) {
    if(degree == 0.0F) {
        return src;
    }
    Matrix matrix = new Matrix();
    matrix.reset();
    matrix.setRotate(degree, src.getWidth() / 2, src.getHeight() / 2);
    Bitmap resultBitmap = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
    boolean filter = true;
    if(resultBitmap == null) {
        LogUtil.e(TAG, "resultBmp is null: ");
        filter = true;
    } else {
        filter = false;
    }

    if(resultBitmap != src) {
        src.recycle();
    }
    LogUtil.d(TAG, "filter: " + filter + "  degree:" + degree);
    return resultBitmap;
}
 
Example 7
Project: snippety   File: MultiColorSpan.java   Source Code and License Vote up 5 votes
@Override
public void updateDrawState(TextPaint paint) {
    paint.setStyle(Paint.Style.FILL);
    Shader shader = new LinearGradient(0, 0, 0, paint.getTextSize() * colors.length, colors, null,
            Shader.TileMode.MIRROR);
    Matrix matrix = new Matrix();
    matrix.setRotate(angle);
    shader.setLocalMatrix(matrix);
    paint.setShader(shader);
}
 
Example 8
Project: Accessibility   File: BitmapUtils.java   Source Code and License Vote up 5 votes
/**
     * 用于压缩时旋转图片
     *
     * @throws IOException
     * @throws OutOfMemoryError
     */
    public static Bitmap rotateBitmap(String srcFilePath, Bitmap bitmap) throws IOException, OutOfMemoryError {
        float degree = 0F;
        try {
            ExifInterface exif = new ExifInterface(srcFilePath);
            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90F;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180F;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270F;
                    break;
                default:
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
//            01-23 11:03:04.040 W/ExifInterface(29568): Invalid image.
//            01-23 11:03:04.040 W/ExifInterface(29568): java.io.IOException: Invalid marker: 89
//            01-23 11:03:04.040 W/ExifInterface(29568): 	at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1656)
//            01-23 11:03:04.040 W/ExifInterface(29568): 	at android.media.ExifInterface.loadAttributes(ExifInterface.java:1360)
//            01-23 11:03:04.040 W/ExifInterface(29568): 	at android.media.ExifInterface.<init>(ExifInterface.java:1064)
        }

        Matrix matrix = new Matrix();
        matrix.setRotate(degree, bitmap.getWidth(), bitmap.getHeight());
        Bitmap b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        if (bitmap != b2) {
            bitmap.recycle();
            bitmap = b2;
        }
        return bitmap;
    }
 
Example 9
Project: Ec2m   File: CamaraActivity.java   Source Code and License Vote up 5 votes
@Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                Matrix matrix = new Matrix();
                matrix.setRotate(270);

                File jpgFile = new File(Environment.getExternalStorageDirectory() + "/DCIM/camera");
                if (!jpgFile.exists()) {
                    jpgFile.mkdir();
                }
                File jpgFile1 = new File(jpgFile.getAbsoluteFile(), System.currentTimeMillis() + ".jpg");
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                FileOutputStream fos = new FileOutputStream(jpgFile1);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
//                ToastUtils.show(getApplicationContext(), getString(R.string.save_success));
                fos.close();
                Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                Uri uri = Uri.fromFile(jpgFile1);
                intent.setData(uri);
                sendBroadcast(intent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (Build.VERSION.SDK_INT >= 24) {
                    reset();
                }
                isTakingPhoto = false;
            }
        }
 
Example 10
Project: GitHub   File: OrientedDrawableTest.java   Source Code and License Vote up 5 votes
@Test
public void testCreation_hundredAndEightyDegrees() {
  OrientedDrawable drawable =
      new OrientedDrawable(mDrawable, 180, ExifInterface.ORIENTATION_ROTATE_180);
  drawable.setBounds(mBounds);
  drawable.draw(mCanvas);

  Matrix expectedMatrix = new Matrix();
  expectedMatrix.setRotate(180, drawable.getBounds().centerX(), drawable.getBounds().centerY());
  assertFalse(drawable.mRotationMatrix.isIdentity());
  AndroidGraphicsTestUtils.assertEquals(expectedMatrix, drawable.mRotationMatrix);
  verifySetBounds(expectedMatrix);
}
 
Example 11
Project: ArtOfAndroid   File: MyAppWidgetProvider.java   Source Code and License Vote up 5 votes
/**
 * 旋转图片
 */
private Bitmap rotateBitmap(Context context, Bitmap srcBitmap, float degree) {
    Matrix matrix = new Matrix();
    matrix.reset();
    matrix.setRotate(degree);
    Bitmap tempBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
    return tempBitmap;
}
 
Example 12
Project: GitHub   File: OrientedDrawableTest.java   Source Code and License Vote up 5 votes
@Test
public void testCreation_transpose() {
  OrientedDrawable drawable =
      new OrientedDrawable(mDrawable, 0, ExifInterface.ORIENTATION_TRANSPOSE);
  drawable.setBounds(mBounds);
  drawable.draw(mCanvas);

  Matrix expectedMatrix = new Matrix();
  expectedMatrix.setRotate(270, drawable.getBounds().centerX(), drawable.getBounds().centerY());
  expectedMatrix.postScale(1, -1);
  assertFalse(drawable.mRotationMatrix.isIdentity());
  AndroidGraphicsTestUtils.assertEquals(expectedMatrix, drawable.mRotationMatrix);
  verifySetBounds(expectedMatrix);
}
 
Example 13
Project: Uygulama-Android   File: MainActivity.java   Source Code and License Vote up 5 votes
/**
 * Fetches a bitmap image from the device given the image's uri.
 * @param imageUri Uri of the image on the device (either in the gallery or from the camera).
 * @return A Bitmap representation of the image on the device, correctly orientated.
 */
private Bitmap fetchBitmapFromUri(Uri imageUri) {
    try {
        // Fetch the Bitmap from the Uri.
        Bitmap selectedImage = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);

        // Fetch the orientation of the Bitmap in storage.
        String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
        Cursor cursor = getContentResolver().query(imageUri, orientationColumn, null, null, null);
        int orientation = 0;
        if (cursor != null && cursor.moveToFirst()) {
            orientation = cursor.getInt(cursor.getColumnIndex(orientationColumn[0]));
        }
        if(cursor != null) {
            cursor.close();
        }

        // Rotate the bitmap with the found orientation.
        Matrix matrix = new Matrix();
        matrix.setRotate(orientation);
        selectedImage = Bitmap.createBitmap(selectedImage, 0, 0, selectedImage.getWidth(), selectedImage.getHeight(), matrix, true);

        return selectedImage;

    } catch (IOException e) {
        showDialog(R.string.error_title_default, e.getMessage(), true);
        e.printStackTrace();
        return null;
    }
}
 
Example 14
Project: CameraKitView   File: Camera2.java   Source Code and License Vote up 5 votes
void setManualFocusAt(int x, int y) {
    int mDisplayOrientation = mWindowManager.getDefaultDisplay().getRotation();
    float points[] = new float[2];
    points[0] = (float) x / mTextureView.getWidth();
    points[1] = (float) y / mTextureView.getHeight();
    Matrix rotationMatrix = new Matrix();
    rotationMatrix.setRotate(mDisplayOrientation, 0.5f, 0.5f);
    rotationMatrix.mapPoints(points);
    if (mPreviewRequestBuilder != null) {
        mIsManualFocusing = true;
        updateManualFocus(points[0], points[1]);
        if (mPreviewSession != null) {
            try {
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CaptureRequest.CONTROL_AF_TRIGGER_START);
                mPreviewSession.capture(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
                mPreviewSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                    null, mBackgroundHandler);
            } catch (CameraAccessException | IllegalStateException e) {
                Log.e(TAG, "Failed to set manual focus.", e);
            }
        }
        resumeAutoFocusAfterManualFocus();
    }
}
 
Example 15
Project: Cluttr   File: BitmapUtils.java   Source Code and License Vote up 5 votes
/**
 * Rotate the given bitmap by the given degrees.<br>
 * New bitmap is created and the old one is recycled.
 */
private static Bitmap rotateAndFlipBitmapInt(Bitmap bitmap, int degrees, boolean flipHorizontally, boolean flipVertically) {
    if (degrees > 0 || flipHorizontally || flipVertically) {
        Matrix matrix = new Matrix();
        matrix.setRotate(degrees);
        matrix.postScale(flipHorizontally ? -1 : 1, flipVertically ? -1 : 1);
        Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        if (newBitmap != bitmap) {
            bitmap.recycle();
        }
        return newBitmap;
    } else {
        return bitmap;
    }
}
 
Example 16
Project: utils-android   File: BitmapUtils.java   Source Code and License Vote up 4 votes
/**
 * Поворачивает bitmap в зависимости от поворота, заданного в EXIF тегах
 * Использование: BitmapUtils.rotateImage(bitmap, BitmapUtils.getImageRotationDegree(fileName))
 */
public static Bitmap rotateImage(Bitmap bitmap, int orientation) {
    Matrix matrix = new Matrix();
    switch (orientation) {
        case ExifInterface.ORIENTATION_NORMAL:
            return bitmap;
        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            matrix.setScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.setRotate(180);
            break;
        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            matrix.setRotate(180);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_TRANSPOSE:
            matrix.setRotate(90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.setRotate(90);
            break;
        case ExifInterface.ORIENTATION_TRANSVERSE:
            matrix.setRotate(-90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.setRotate(-90);
            break;
        default:
            return bitmap;
    }
    try {
        Bitmap bmRotated = Bitmap.createBitmap(bitmap,
                                               0,
                                               0,
                                               bitmap.getWidth(),
                                               bitmap.getHeight(),
                                               matrix,
                                               true);
        bitmap.recycle();
        return bmRotated;
    } catch (OutOfMemoryError e) {
        return bitmap;
    }
}
 
Example 17
Project: MOAAP   File: MainActivity.java   Source Code and License Vote up 4 votes
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {

        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                return bitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.setRotate(-90);
                break;
            default:
                return bitmap;
        }
        try {
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle();
            return bmRotated;
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            return null;
        }

    }
 
Example 18
Project: CustomAndroidOneSheeld   File: DefaultIndicatorLayout.java   Source Code and License Vote up 4 votes
public DefaultIndicatorLayout(Context context, PullToRefreshBase.Mode mode) {
	super(context);
	mArrowImageView = new ImageView(context);

	Drawable arrowD = getIconDrawable(context, mode);
	mArrowImageView.setImageDrawable(arrowD);
	
	final int padding = getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding);
	mArrowImageView.setPadding(padding, padding, padding, padding);
	addView(mArrowImageView);

	int inAnimResId, outAnimResId;
	switch (mode) {
		case PULL_FROM_END:
			inAnimResId = R.anim.slide_in_from_bottom;
			outAnimResId = R.anim.slide_out_to_bottom;
			setBackgroundResource(R.drawable.indicator_bg_bottom);

			// Rotate Arrow so it's pointing the correct way
			mArrowImageView.setScaleType(ScaleType.MATRIX);
			Matrix matrix = new Matrix();
			matrix.setRotate(180f, arrowD.getIntrinsicWidth() / 2f, arrowD.getIntrinsicHeight() / 2f);
			mArrowImageView.setImageMatrix(matrix);
			break;
		default:
		case PULL_FROM_START:
			inAnimResId = R.anim.slide_in_from_top;
			outAnimResId = R.anim.slide_out_to_top;
			setBackgroundResource(R.drawable.indicator_bg_top);
			break;
	}

	mInAnim = AnimationUtils.loadAnimation(context, inAnimResId);
	mInAnim.setAnimationListener(this);

	mOutAnim = AnimationUtils.loadAnimation(context, outAnimResId);
	mOutAnim.setAnimationListener(this);

	final Interpolator interpolator = new LinearInterpolator();
	mRotateAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
			0.5f);
	mRotateAnimation.setInterpolator(interpolator);
	mRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
	mRotateAnimation.setFillAfter(true);

	mResetRotateAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f,
			Animation.RELATIVE_TO_SELF, 0.5f);
	mResetRotateAnimation.setInterpolator(interpolator);
	mResetRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
	mResetRotateAnimation.setFillAfter(true);

}
 
Example 19
Project: CameraFragment   File: ImageLoader.java   Source Code and License Vote up 4 votes
private Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
    Matrix matrix = new Matrix();
    switch (orientation) {
        case ExifInterface.ORIENTATION_NORMAL:
            return bitmap;
        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            matrix.setScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.setRotate(180);
            break;
        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            matrix.setRotate(180);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_TRANSPOSE:
            matrix.setRotate(90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.setRotate(90);
            break;
        case ExifInterface.ORIENTATION_TRANSVERSE:
            matrix.setRotate(-90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.setRotate(-90);
            break;
        default:
            return bitmap;
    }

    try {
        Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        bitmap.recycle();
        return bmRotated;
    } catch (OutOfMemoryError ignore) {
        return null;
    }
}
 
Example 20
Project: Android-UtilCode   File: ImageUtils.java   Source Code and License Vote up 3 votes
/**
 * 旋转图片
 *
 * @param src     源图片
 * @param degrees 旋转角度
 * @param px      旋转点横坐标
 * @param py      旋转点纵坐标
 * @param recycle 是否回收
 * @return 旋转后的图片
 */
public static Bitmap rotate(Bitmap src, int degrees, float px, float py, boolean recycle) {
    if (isEmptyBitmap(src)) return null;
    if (degrees == 0) return src;
    Matrix matrix = new Matrix();
    matrix.setRotate(degrees, px, py);
    Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
    if (recycle && !src.isRecycled()) src.recycle();
    return ret;
}