Почему сохранение растрового изображения занимает так много времени?

Итак, у меня есть приложение в Google Glass, которое делает снимок, затем преобразует его в оттенки серого и перезаписывает исходное изображение в памяти:

private void rGBProcessing (final String picturePath, Mat image) {
//BitmapFactory Creates Bitmap objects from various sources,
//including files, streams, and byte-arrays
    Bitmap myBitmapPic = BitmapFactory.decodeFile(picturePath);
    image = new Mat(myBitmapPic.getWidth(), myBitmapPic.getHeight(), CvType.CV_8UC4);
    Mat imageTwo = new Mat(myBitmapPic.getWidth(), myBitmapPic.getHeight(), CvType.CV_8UC1);
    Utils.bitmapToMat(myBitmapPic, image);
    Imgproc.cvtColor(image, imageTwo, Imgproc.COLOR_RGBA2GRAY);
    Utils.matToBitmap(imageTwo, myBitmapPic);

    FileOutputStream out = null;
    try {
        out = new FileOutputStream(picturePath);
        myBitmapPic.compress(Bitmap.CompressFormat.PNG, 100, out); 
    // PNG is a lossless format, the compression factor (100) is ignored
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) {
                out.close();
            }
         } catch (IOException e) {
            e.printStackTrace();
        }
    }

Серое растровое изображение не полностью отображается в памяти с помощью средства просмотра фотографий Windows до тех пор, пока Google Glass не будет отключен от отладочного компьютера, а затем снова подключен. Иногда можно просмотреть половину изображения в градациях серого, но это все. Я изменил код, чтобы показать изображение, а не сохранять его во внутреннюю память, и это было быстро и успешно, что заставляет меня думать, что проблема связана с чтением изображения в градациях серого во внутреннюю память:

FileOutputStream out = null;
        try {
            out = new FileOutputStream(picturePath);
            myBitmapPic.compress(Bitmap.CompressFormat.PNG, 100, out); 
        // PNG is a lossless format, the compression factor (100) is ignored
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
             } catch (IOException e) {
                e.printStackTrace();
            }
        }

Любые объяснения или предложения приветствуются. Спасибо.


person MichaelAndroidNewbie    schedule 22.02.2015    source источник
comment
Почему сохранение растрового изображения занимает так много времени? -- используйте Traceview и узнайте. Серое растровое изображение не полностью отображается в памяти с помощью средства просмотра фотографий Windows до тех пор, пока Google Glass не будет отключен от отладочного компьютера, а затем снова подключен — используйте MediaScannerConnection и scanFile(), чтобы получить файл, проиндексированный MediaStore. Иногда можно просмотреть половину изображения в градациях серого, но это все -- вызовите getFD().sync() на FileOutputStream после вызова flush(), но до вызова close().   -  person CommonsWare    schedule 22.02.2015


Ответы (1)


Я не использую Google Glass, но столкнулся с той же проблемой. Поэтому я собираюсь документировать свои выводы здесь.

Мое растровое изображение долго сохранялось. Мне потребовалось почти 4 секунды, чтобы сохранить растровое изображение размером 1200x1200, а окончательный размер сохраненного файла составил 2 МБ. Но мне не нужен был такой уровень четкости и размер файла. Когда я имею в виду «сохранить», я имею в виду фактическое сохранение только на диск, а не время, затрачиваемое ОС Android на обнаружение его как элемента мультимедиа.


АКТУАЛЬНОЕ СОХРАНЕНИЕ: попробуйте следующее, если вы обнаружите, что сохранение растрового изображения происходит медленно:

  1. Старайтесь использовать формат JPEG и используйте PNG только тогда, когда это абсолютно необходимо. Используйте 1_
  2. Если вы создаете растровое изображение и вас не волнует прозрачность, используйте Bitmap.Config.RGB_565 вместо Bitmap.Config.ARGB_8888.

    Используйте Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);


ОБНАРУЖЕНИЕ В ФАЙЛОВОМ МЕНЕДЖЕРЕ:

После того, как вы сохранили растровое изображение как File в хранилище, ОС Android не сразу отобразит этот файл в диспетчере файлов или в проводнике при подключении его к компьютеру. Чтобы сделать это обнаружение быстро, вам нужно использовать MediaScannerConnection.

MediaScannerConnection.scanFile(getActivity(), new String[]{file.toString()}, null, null);
person Henry    schedule 23.10.2015