I have a camera application which is able to capture images and record videos. However, when capturing images or recording videos from the device front facing camera the result is flipped, like you are looking at the mirror. I want to flip it again so it will look normal. I managed to do this with images by flipping the Bitmap using Matrix :
public Bitmap flip(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix matrix = new Matrix();
float[] mirrorY = {-1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
matrix.postConcat(matrixMirrorY);
matrix.postRotate(90);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
}
I can't figure out how to flip videos taken by MediaRecorder, I know I can run a ffmpeg command:
-i /pathtooriginalfile/originalfile.mp4 -vf hflip -c:a copy /pathtosave/flippedfile.mp4
but I don't know how to run a ffmpeg command from code and I can't find a different way. There are a lot of topics discussing this issue but I couldn't find a solution to work. Notice: It is possible, Snapchat got this to work somehow.
Thanks.
P.S Sorry for my English
Capturing images or recording video using front camera will always gives flipped images, which is expected as front camera works like you are looking at the mirror.
After getting the picture from the camera, flip the image back by drawing the image into a new context.
Please try below code snippets. Refer Android- Taking a picture from front facing camera rotates the photo
Matrix rotateRight = new Matrix();
rotateRight.preRotate(90);
if(android.os.Build.VERSION.SDK_INT>13 && CameraActivity.frontCamera) {
float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1};
rotateRight = new Matrix();
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
rotateRight.postConcat(matrixMirrorY);
rotateRight.preRotate(270);
}
final Bitmap rImg= Bitmap.createBitmap(img, 0, 0,
img.getWidth(), img.getHeight(), rotateRight, true);
Related
I have an ImageView and VideoView on my screen.
My Activity is always in a portrait mode (and i can't rotate it because of another elements).
How can i rotate image/video if it was captured in landscape mode?
Show like on this image
instead of
public Bitmap rotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
// Perform matrix rotations/mirrors depending on camera that took the photo
if (cameraCurrentID == Camera.CameraInfo.CAMERA_FACING_FRONT) {
float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
matrix.postConcat(matrixMirrorY);
}
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}
I am trying to take a picture with the max camera size and then scale it to 1080x1776, with a quality of 80% and saving the bitmap as .jpeg. Even though I am pretty sure that I am rotating the matrix in the wrong way, since the only way to get 1080x1776 working is to set the parameters the other way around in createScaledBitmap, this code works with my Nexus 5.
When I tried the same code on a One Plus, I got a really low resolution quality. I don't understand why since the code works on a Nexus 5, which has similar specs, it shouldn't be working for the one plus. On the One Plus the picture is scaling in the right way 1080x1776, but the quality is bad.
Does anyone know why? Same code, new phones, different results? I have also tried the code on a Nexus 7 and still I do have bad pictures. Why would this code work on my nexus 5?
Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap imageScaled = Bitmap.createScaledBitmap(image, 1776, 1080, true);
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
matrix.postConcat(matrixMirrorY);
}
matrix.postRotate(90);
Bitmap rotatedScaledImage = Bitmap.createBitmap(imageScaled, 0,
0, imageScaled.getWidth(), imageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledImage.compress(Bitmap.CompressFormat.JPEG, 80, bos);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(dial, 0, 0, new Paint());
Matrix matrix = new Matrix();
matrix.setRotate(80);
matrix.preTranslate(-arrow.getWidth() / 2, -arrow.getHeight());
matrix.postTranslate(arrow.getWidth() / 2, arrow.getHeight());
Bitmap bb = Bitmap.createBitmap(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), matrix, true);
canvas.drawBitmap(bb, centerXY - bb.getWidth() / 2, 0, new Paint());
I searched and read many post about "how rotate a image around center in android". But my code is does not work. What am I doing wrong? You will see result by screenshot:
I am trying to rotate a bitmap image 90 degrees to change it from a landscape format to a portrait format. Example:
[a, b, c, d]
[e, f, g, h]
[i, j, k, l]
rotated 90 degree clockwise becomes
[i,e,a]
[j,f,b]
[k,g,c]
[l,h,d]
Using the code below (from an online example) the image is rotated 90 degrees but retains the landscape aspect ratio so you end up with a vertically squashed image. Am I doing something wrong? Is there another method I need to use? I am also willing to rotate the jpeg file that I'm using to create the bitmap if that is easier.
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(90);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOriginal, 0, 0, widthOriginal, heightOriginal, matrix, true);
This is all you need to rotate the image:
Matrix matrix = new Matrix();
matrix.postRotate(90);
rotated = Bitmap.createBitmap(original, 0, 0,
original.getWidth(), original.getHeight(),
matrix, true);
In your code sample, you included a call to postScale. Could that be the reason your image is being stretched? Perhaps take that one out and do some more testing.
Here's how you would rotate it properly (this insures proper rotation of the image)
public static Bitmap rotate(Bitmap b, int degrees) {
if (degrees != 0 && b != null) {
Matrix m = new Matrix();
m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2);
try {
Bitmap b2 = Bitmap.createBitmap(
b, 0, 0, b.getWidth(), b.getHeight(), m, true);
if (b != b2) {
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex) {
throw ex;
}
}
return b;
}
This code worked great for me:
Matrix matrix = new Matrix();
matrix.setRotate(90, 0, 0);
matrix.postTranslate(original.getHeight(), 0);
rotatedBitmap = Bitmap.createBitmap(newWidth, newHeight, original.getConfig());
Canvas tmpCanvas = new Canvas(rotatedBitmap);
tmpCanvas.drawBitmap(original, matrix, null);
tmpCanvas.setBitmap(null);
check the canvas size where you draw the bitmap, maybe your canvas is still landscape, so only the square part of the rotated bitmap could be seen.
I have a rectangle-shaped Bitmap, which I need to rotate it by 90 degrees clockwise or counter-clockwise.
I can do the rotation using this code:
Matrix matrix = new Matrix();
matrix.setRotate(90, originalBitmap.getWidth()/2, originalBitmap.getHeight()/2);
return Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), matrix, true);
However, this code rotates image "in-place" using old values for height/width. And the resulting image looks stretched and ugly.
Is there any good way to rotate the image by 90 degrees into new height/width? Probably, one possible solution is to modify dimensions of the original bitmap first?
Thanks
Don't you use old values while creating new bitmap? Just replace them in the last line:
return Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth()/2, originalBitmap.getHeight()/2, matrix, true);