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);
Related
I am converting each frame retrieved from the camera into a bitmap and i display it on an ImageView, but i found that the imageView contains a rotated bitmap so i wanted to rotate the bitmap 90 degrees to set it right. to achieve this,
i wrote the below code to rotate the bitmap 90 degrees, but at run time i receive
bitmap size exceeds 32bits
i referred to some posts to solve this issue, and one of them suggested to recycle each bitmap used, but it did not solve the problem.
please let me know why i am getting this error and how to solve it?
code:
#Override
protected void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
Bitmap b = values[0];
Matrix matrix = new Matrix();
matrix.postScale(b.getWidth()-10, b.getHeight()-10);
matrix.postRotate(90);
Bitmap resizedBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
mIVEdges.setImageBitmap(resizedBitmap);
b.recycle();
}
If you have 100x100 pixel bitmap, then
matrix.postScale(b.getWidth()-10, b.getHeight()-10);
will cause new bitmap to be scaled with 90 scale factor.
matrix.postScale(90, 90);
So output of new Bitmap is 9000x9000 pixel.
If you want to reduce size of new bitmap, you want to use scale factor > 0.0 and < 1.0
matrix.postScale(0.9f, 0.9f);
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);
I read many posts there? But i don't find correctly answer.
I try do something this:
#Override
public void onPictureTaken(byte[] paramArrayOfByte, Camera paramCamera) {
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(paramArrayOfByte, 0,
paramArrayOfByte.length);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
FileOutputStream os = new ileOutputStream(Singleton.mPushFilePath);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
height, matrix, false);
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 95, os);
os.close();
...
Is there a way to rotate picture, without using BitmapFactory? I want rotate picture without loss of quality!
Perhaps you can take the picture already rotated as you desire using Camera.setDisplayOrientation? Check Android camera rotate. Further, investigate Camera.Parameters.setRotation(). One of these techniques should do the trick for you.
Otherwise your code looks fine except for using parameter 95 on Bitmap.compress, you need to use 100 for lossless compression.
To avoid out-of-memory exception, use Camera.Parameters.setPictureSize() to take a lower resolution picture (e.g. 3Mpx). i.e. do you really need an 8Mpx photo? Make sure to use Camera.Parameters.getSupportedPictureSizes() to determine the supported sizes on your device.
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);
I have a picture (bitmap) and I want to draw some shapes and rotated
text on it.
This works fine as long as the picture doesn't get too large. However,
when using a picture (2560 x 1920 pixels)taken with the build-in
camera of my android 2.1 phone, the result is distorted.
It looks like the rotation back, after drawing the rotated text, has
not been completed. Also, the distortion point is not always the same,
like it depends on the cpu usage.
You can see some resulting pictures here:
http://dl.dropbox.com/u/4751612/Result1.png
http://dl.dropbox.com/u/4751612/Result2.png
The code is executed inside a AsyncTask. The strange this is that this code works fine in one Activity, but not in another. In both activities the AsyncTask is executed when a button is clicked.
These are some excerpts of the code I'm using.
// Load the image from the MediaStore
c = MediaStore.Images.Media.query(context.getContentResolver(),
Uri.parse(drawing.fullImage), new String[] {MediaColumns.DATA});
if (c != null && c.moveToFirst()) {
imageFilePath = c.getString(0);
bitmap = ImageUtil.getBitmap(new File(imageFilePath), 10000);
}
c.close();
// Create a canvas to draw on
drawingBitmap = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(drawingBitmap);
// Draw image
canvas.drawBitmap(bitmap, 0, 0,
MeasureFactory.getMeasurePaint(context));
// calculate text width
rect = new Rect();
paint.getTextBounds(text, 0, text.length(), rect);
// Draw rotated text
canvas.save();
canvas.rotate(-angle, centerPoint.x, centerPoint.y);
canvas.drawText(text, centerPoint.x-Math.abs(rect.exactCenterX()),
Math.abs(centerPoint.y-rect.exactCenterY()), paint);
canvas.restore();
// Upload the bitmap to the Media Library
Uri uri =
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
OutputStream outStream = getContentResolver().openOutputStream(uri);
drawingBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
outStream.flush();
outStream.close();
Thanks in advance for any help.
Since it works as long as the resolution isn't too high, I would just rescale all images to something that works.
You can accomplish this using
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 800 /* width */, 600 /* height */, true);
This turned out to be a memory problem although no OutOfMemoryException was visible in the log.
So, I "solved" it by scaling the image if the resolution is too high, as suggested by ingo. The problem is that I don't know how to determine the limits of a device. I suppose they are different for every device and depends on the current memory usage.