#java #android #image-processing #bitmap
#java #Android #обработка изображений #растровое изображение
Вопрос:
У меня есть следующий код для сохранения изображения в каталоге кэша моего приложения. Метод вызывается в отдельном Runnable()
, который, как я надеялся, ускорит работу приложения. В нынешнем виде сжатие растрового изображения очень дорого для процессора и приводит к тому, что остальная часть приложения работает очень медленно. Как я могу ускорить это?
public void combineImages(Bitmap bmp, int count, int count2){
Bitmap bottomImage = bmp.copy(Config.RGB_565, true);
float width = bmp.getWidth();
float height = bmp.getHeight();
bmp.recycle();
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
Bitmap topImage = myBitmap.copy(Config.ARGB_4444, true);
myBitmap.recycle();
myBitmap = null;
Canvas comboImage = new Canvas(bottomImage);
// Then draw the second on top of that
comboImage.drawBitmap(topImage, (width / 2) - 200, (height / 2) - 160, null);
topImage.recycle();
topImage = null;
// bottomImage is now a composite of the two.
// To write the file out to the Cache:
OutputStream os = null;
try {
os = new FileOutputStream(getApplicationContext().getCacheDir() "/" path);
bottomImage.compress(CompressFormat.PNG, 50, os); //Here it is most expensive and what slows the app down
} catch (IOException e) {
e.printStackTrace();
}
}
Комментарии:
1. в какой поток вы отправляете
Runnable
?2. @techiServices: Оно отправляется в другой исполняемый экземпляр, который, в свою очередь, запускается в главном потоке пользовательского интерфейса.
Ответ №1:
Вы должны использовать отдельный поток для запуска метода, либо создав новый внутренний класс, который расширяет Thread
и вызывает метод, либо создав новый Thread
и передав Runnable
в качестве аргумента конструктора. Если это текущая задача, то есть вам нужно обработать много растровых изображений, вы можете захотеть взглянуть на HandlerThread
или IntentService
.
Комментарии:
1. У меня это уже есть, у меня есть поток пользовательского интерфейса, в котором я создаю объект Thread, который вызывает метод SaveImage() в его методе Runnable(), внутри этого метода есть другой объект Thread, а в методе Runnable() вызывается приведенный выше код. Я вообще не думаю, что это проблема с потоками, приложение работает очень быстро, когда не используется метод сжатия для растрового объекта.
2. @SamRowley: извините, я неправильно понял, из вашего комментария выяснилось, что вы запускали этот метод в потоке пользовательского интерфейса. Вы тестируете на физическом устройстве или эмуляторе? Глядя на исходный код Android, метод compress вызывает встроенную функцию.
3. Я запускаю его на 2 разных устройствах (HTC Desire и Samsung Nexus S), он ускорился, изменив формат сжатия на JPEG, а не PNG на Nexus, но на Desire он по-прежнему работает очень медленно.
4. @techiServices — Да, у меня есть, я использовал setDaemon (true); для потоков, которые я хочу, прямо в фоновом режиме. Я предполагаю, что это аппаратная проблема, которая медленно работает на HTC, она очень хорошо работает на Nexus S.
5. @SamRowley: я бы предположил то же самое, поскольку метод compress запускает встроенную функцию c, однако приоритет, о котором я говорю, устанавливается с помощью
Thread.setPriority
метода или конструктора, например, с помощьюThread.MIN_PRIORITY
.