需要25秒以上才能将位图从相机保存到手机

时间:2015-05-27 17:32:06

标签: java android bitmap camera bytearray

我正在制作相机应用程序。

由于有些手机没有写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

1 个答案:

答案 0 :(得分:1)

  

你能告诉我为什么代码这么慢

也许还有其他原因,您正在将图像写入文件,从文件中重新读取相同的图像,进行转换,然后将图像写回文件。这将花费很多时间。

  

注意:如果我只保存一次图像(即方向错误),则只需几秒钟。

这是因为你做的工作少得多,只包括大约33%的磁盘I / O,而且磁盘I / O会很慢。

  

因为我认为我不应该从字节[]

中读取EXIF数据

如果你作为一个小孩或某物被byte[]恶意攻击,我道歉。但是,如果要获得更好的性能,则必须从现有的映像内存副本中读取EXIF数据。