39

By using this code we can rotate an image:

public static Bitmap RotateBitmap(Bitmap source, float angle) {
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);
      return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

But how can we flip an image horizontally or vertically?

weston
  • 54,145
  • 21
  • 145
  • 203
activity
  • 2,653
  • 3
  • 20
  • 44

6 Answers6

71

Given cx,cy is the centre of the image:

Flip in x:

matrix.postScale(-1, 1, cx, cy);

Flip in y:

matrix.postScale(1, -1, cx, cy);

Altogether:

public static Bitmap createFlippedBitmap(Bitmap source, boolean xFlip, boolean yFlip) {
    Matrix matrix = new Matrix();
    matrix.postScale(xFlip ? -1 : 1, yFlip ? -1 : 1, source.getWidth() / 2f, source.getHeight() / 2f);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
weston
  • 54,145
  • 21
  • 145
  • 203
14

Using Kotlin and extension functions:

// To flip horizontally:
fun Bitmap.flipHorizontally(): Bitmap {
    val matrix = Matrix().apply { postScale(-1f, 1f, width / 2f, height / 2f) }
    return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}

// To flip vertically:
fun Bitmap.flipVertically(): Bitmap {
    val matrix = Matrix().apply { postScale(1f, -1f, width / 2f, height / 2f) }
    return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}
tom
  • 21,844
  • 6
  • 43
  • 36
Kit Mak
  • 231
  • 2
  • 4
10

Short extension for Kotlin

private fun Bitmap.flip(x: Float, y: Float, cx: Float, cy: Float): Bitmap {
    val matrix = Matrix().apply { postScale(x, y, cx, cy) }
    return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}

And usage:

For horizontal flip :-

val cx = bitmap.width / 2f
val cy = bitmap.height / 2f
val flippedBitmap = bitmap.flip(-1f, 1f, cx, cy)
ivMainImage.setImageBitmap(flippedBitmap)

For vertical flip :-

val cx = bitmap.width / 2f
val cy = bitmap.height / 2f
val flippedBitmap = bitmap.flip(1f, -1f, cx, cy)
ivMainImage.setImageBitmap(flippedBitmap)
Mahesh Babariya
  • 4,560
  • 6
  • 39
  • 54
  • 1
    I would put the `cx` and `cy` calculation inside the `flip` method. `Matrix().apply { postScale(x, y, width / 2f, height / 2f) }` Also your `flip` method is no different to a `scale` method extension. – weston May 31 '18 at 11:29
1

Just use below codes:

private fun setVerticalFlip() {
    if (binding.imgReal.scaleX == 1.0f) {
        binding.imgReal.scaleX = -1.0f
    } else {
        binding.imgReal.scaleX = 1.0f
    }
}

private fun setHorizontalFlip() {
    if (binding.imgReal.scaleY == 1.0f) {
        binding.imgReal.scaleY = -1.0f
    } else {
        binding.imgReal.scaleY = 1.0f
    }
}
Ola Ström
  • 4,136
  • 5
  • 22
  • 41
Ahmet B.
  • 1,290
  • 10
  • 20
0

Horizontal and vertical flips for Bitmap bms (source).

Matrix matrix = new Matrix();
// for horizontal flip
matrix.setScale(-1, 1);
matrix.postTranslate( bms.getWidth(),0);
// for vertical flip
matrix.setScale( 1,-1);
matrix.postTranslate( 0, bms.getHeight());
Bitmap bm = Bitmap.createBitmap( bms, 0, 0, bms.getWidth(), bms.getHeight(), matrix, true);
Style-7
  • 985
  • 12
  • 27
-1

Its all about the matrix you use. To flip it around the x axes, use [[-1,0],[0, 1]]. For the y axes, use [[1,0],[0,-1]]. The important thing here is that the absolute value of the determinant is 1, so it won't scale. And the - basically inverses the location around the given axes.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Problem is, an x of 100 becomes an x of -100, this needs to happen around the centre of the image, not the origin. – weston Apr 08 '16 at 07:43
  • Then translate the canvas first. – Gabe Sechan Apr 08 '16 at 07:44
  • 2
    If you mean apply a translate to the matrix, then you must also translate afterwards too. i.e. you can `translate(-cx/2,-cy/2), scale, translate(cx/2,cy/2)`. – weston Apr 08 '16 at 07:50