我正在制作相机应用程序。
由于有些手机没有写EXIF方向数据,因此出现了很多问题。因此,我得到位图,保存它(因为我认为我不应该从byte []读取EXIF数据),然后旋转位图,然后保存在原始文件上。
它有效,方向问题已修复。问题是它在一些顶级的手机上花了我25秒或更长时间。你能告诉我为什么我的代码如此缓慢或建议我如何找到问题吗?
注意:如果我只保存一次图像(即方向错误),则只需几秒钟。
这是我的图像捕获回调:
private Camera.PictureCallback pictureCallback = new Camera.PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("EditPhotoFragment", "Error creating media file, check storage permissions");
return;
}
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.flush();
fos.close();
orientPicture(pictureFile);
//TODO async
galleryAddPic(pictureFile);
} catch (FileNotFoundException e) {
Log.d("EditPhotoFragment", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("EditPhotoFragment", "Error accessing file: " + e.getMessage());
}
}
};
这是我定位和重新保存图像的地方:
private Bitmap orientPicture(File pictureFile)
{
Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
Uri uri = Uri.parse(pictureFile.toString());
ExifInterface exif = null;
try{
exif = new ExifInterface(uri.getPath());
}catch (Exception e)
{
e.printStackTrace();
}
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Matrix matrix = new Matrix();
int rotationInDegrees = 0;
//If the orientation tag is missing need to manually rotate it by the 'default' camera
//orientation and if its front facing need to do 360 - the camera rotation value
if(exifOrientation == ExifInterface.ORIENTATION_UNDEFINED)//All phones in this bucket can go fuck themselves
{
Camera.CameraInfo info = new Camera.CameraInfo();
if(_cameraPreview.isBackFacing())
{
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
}else
{
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, info);
}
rotationInDegrees = info.orientation; //set it to the default camera orientation
}else
{
rotationInDegrees = exifToDegrees(exifOrientation);
if(!_cameraPreview.isBackFacing())//handle mirroring of front camera
{
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
rotationInDegrees = 360 - rotationInDegrees; //For the front camera doing 360 - gets the right orientation
}
}
matrix.preRotate(rotationInDegrees);
if(!_cameraPreview.isBackFacing())//mirror it
{
matrix.preScale(1,-1);
}
Bitmap adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//This saves the proper image over top if it
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
adjustedBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
fos.write(byteArray);
fos.flush();
fos.close();
}catch(Exception e)
{
e.printStackTrace();
}
return adjustedBitmap;
}
解 据我所知,我应该阅读exif数据,这是我能够做到的,而不需要外部库,这要归功于: https://stackoverflow.com/a/13581324/3324388
答案 0 :(得分:1)
你能告诉我为什么代码这么慢
也许还有其他原因,您正在将图像写入文件,从文件中重新读取相同的图像,进行转换,然后将图像写回文件。这将花费很多时间。
注意:如果我只保存一次图像(即方向错误),则只需几秒钟。
这是因为你做的工作少得多,只包括大约33%的磁盘I / O,而且磁盘I / O会很慢。
因为我认为我不应该从字节[]
中读取EXIF数据
如果你作为一个小孩或某物被byte[]
恶意攻击,我道歉。但是,如果要获得更好的性能,则必须从现有的映像内存副本中读取EXIF数据。