More advanced rotation than with help of android.graphics.Matrix . - Android android.graphics

Android examples for android.graphics:Matrix

Description

More advanced rotation than with help of android.graphics.Matrix .

Demo Code

/*/*ww w  .  j  a  va2 s. co  m*/
 * The MIT License Copyright (c) 2014 Krayushkin Konstantin (jangokvk@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Main{
    /**
     * Maximum texture size, witch Android could handle. That is, maximum {@link android.graphics.Bitmap}
     * size, witch won't through {@link java.lang.OutOfMemoryError}.
     * <br /><br />
     * <p/>
     * Actually maximum texture size for now is 2048x2048, but here was chosen 2000x2000
     * just in case.
     */
    public static final int MAX_TEXTURE_SIZE = 2000;
    /**
     * More advanced rotation than with help of {@link android.graphics.Matrix}. After rotation
     * source image could be automatically scaled according to the passed <b>scaleType</b>; width and
     * height of the source image will be treated as target width and height for scaling.
     * <br /><br />
     * <b>scaleType</b> could be NULL, than the image would be just rotated without any post scaling.
     * <br /><br />
     * Method will create totally new Bitmap, and the source Bitmap will stay safe
     * ({@link android.graphics.Bitmap#recycle()} won't be called). So, if you don't need the source
     * Bitmap after rotation, you should manually call {@link android.graphics.Bitmap#recycle()} for
     * better memory usage.
     *
     * @param src       source image for rotation
     * @param scaleType scaling option, may be NULL
     * @param degrees   rotation angle in degrees
     * @return rotated image
     *
     * @see android.graphics.Bitmap#recycle()
     */
    public static Bitmap rotate(Bitmap src, ScaleType scaleType, int degrees) {
        degrees = degrees % 360;

        final Matrix m = new Matrix();
        m.setRotate(degrees, src.getWidth() / 2, src.getHeight() / 2);

        if (scaleType != null) {
            double radAngl = Math.toRadians(degrees);
            int resultW = (int) (Math.abs(src.getWidth()
                    * Math.cos(radAngl)) + Math.abs(src.getHeight()
                    * Math.sin(radAngl)));
            int resultH = (int) (Math.abs(src.getWidth()
                    * Math.sin(radAngl)) + Math.abs(src.getHeight()
                    * Math.cos(radAngl)));

            final PointF scales = resolveScale(scaleType, src.getWidth(),
                    src.getHeight(), resultW, resultH);
            m.postScale(scales.x, scales.y);
        }

        return Bitmap.createBitmap(src, 0, 0, src.getWidth(),
                src.getHeight(), m, true);
    }
    /**
     * Wrapper for {@link ru.jango.j0util.BmpUtil.ScaleType#resolveScale(int, int, int, int)}, witch
     * also checks bounds for {@link #MAX_TEXTURE_SIZE}.
     */
    protected static PointF resolveScale(ScaleType scaleType, int destW,
            int destH, int srcW, int srcH) {
        destW = Math.min(destW, MAX_TEXTURE_SIZE);
        destH = Math.min(destH, MAX_TEXTURE_SIZE);

        PointF scales = scaleType.resolveScale(destW, destH, srcW, srcH);
        if (srcW * scales.x > MAX_TEXTURE_SIZE
                || srcH * scales.y > MAX_TEXTURE_SIZE)
            scales = ScaleType.PROPORTIONAL_FIT.resolveScale(destW, destH,
                    srcW, srcH);

        return scales;
    }
}

Related Tutorials