Android: как выполнить это для цикла быстро, как сейчас? - PullRequest
0 голосов
/ 23 марта 2012

Я собираюсь установить Pixel для своего растрового изображения в какой-то определенной точке.

Для этого я использую цикл For. Но так как сканирование всего изображения требует времени. Так какой же вариант может помочь мне выполнить его быстрее.

Это для цикла, как показано ниже:

public void drawLoop(){
    int ANTILAISING_TOLERANCE = 100;

    for(int x = 0; x < mask.getWidth(); x++){
        for(int y = 0; y < mask.getHeight(); y++){

            g = (mask.getPixel(x,y) & 0x0000FF00) >> 8;
            r = (mask.getPixel(x,y) & 0x00FF0000) >> 16;
            b = (mask.getPixel(x,y) & 0x000000FF);

            if(Math.abs(sR-r) < ANTILAISING_TOLERANCE && Math.abs(sG-g) < ANTILAISING_TOLERANCE && Math.abs(sB-b) < ANTILAISING_TOLERANCE)
                colored.setPixel(x, y, (colored.getPixel(x, y) & 0xFFFF0000));
        }
    }

    imageView.setImageBitmap(colored);
    coloreBitmap.add(colored.copy(Config.ARGB_8888, true));
    position = coloreBitmap.size()-1;
    System.out.println("Position in drawFunction is: "+position);
}

Пожалуйста, помогите мне в этом.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 23 марта 2012

У меня тоже была эта проблема.Моя программа проверяет каждый пиксель на растровом изображении, а затем проверяет, превышает ли зеленый цвет (RGB) красный и синий, растровое изображение размером 3264 x 2448 (размер камеры Samsung galaxy s2).требуется 3 секунды для сканирования и проверки всего растрового изображения, довольно быстро, если вы спросите меня.

Это мой код:

try {
                decoder_image = BitmapRegionDecoder.newInstance("yourfilepath",false);              

            } catch (IOException e) {
                e.printStackTrace();
            }

пример filepath: / mnt / sdcard / DCIM / Camera/image.jpg

try {

                    final int width = decoder_image.getWidth();
                    final int height = decoder_image.getHeight();
                    // Divide the bitmap into 1100x1100 sized chunks and process it.
                    // This makes sure that the app will not be "overloaded"
                    int wSteps = (int) Math.ceil(width / 1100.0);
                    int hSteps = (int) Math.ceil(height / 1100.0);
                    Rect rect = new Rect();
                    for (int h = 0; h < hSteps; h++) {
                        for (int w = 0; w < wSteps; w++) {
                            int w2 = Math.min(width, (w + 1) * 1100);
                            int h2 = Math.min(height, (h + 1) * 1100);
                            rect.set(w * 1100, h * 1100, w2, h2);
                            mask = decoder_image.decodeRegion(rect,
                                    null);

                            try {
                                int bWidth = mask.getWidth();
                                int bHeight = mask.getHeight();
                                int[] pixels = new int[bWidth * bHeight];
                                mask.getPixels(pixels, 0, bWidth, 0, 0,
                                        bWidth, bHeight);
                                for (int y = 0; y < bHeight; y++) {
                                    for (int x = 0; x < bWidth; x++) {

                                        int index = y * bWidth + x;
                                        int r = (pixels[index] >> 16) & 0xff; //bitwise shifting
                                        int g = (pixels[index] >> 8) & 0xff;
                                        int b = pixels[index] & 0xff;

                                       if(Math.abs(sR-r) < ANTILAISING_TOLERANCE && Math.abs(sG-g) < ANTILAISING_TOLERANCE && Math.abs(sB-b) < ANTILAISING_TOLERANCE)
                                       colored.setPixel(x, y, (colored.getPixel(x, y) & 0xFFFF0000));
                                        }
                                }
                            } finally {
                                mask.recycle();
                            }
                        }
                    }
                    imageView.setImageBitmap(colored);
                    coloreBitmap.add(colored.copy(Config.ARGB_8888, true));
                    position = coloreBitmap.size()-1;
                    System.out.println("Position in drawFunction is: "+position);
                } finally {
                    decoder_image.recycle();
                }

Я также разрезал их на куски, потому что у samsung galaxy s2 недостаточно памяти для сканирования всего растрового изображения сразу.

Надеюсь, это помогло.

Редактировать:

Я просто замечаю (по моей вине), что речь идет о настройке пикселей, а не только их чтении.Сейчас я попытаюсь сделать так, чтобы он соответствовал вашему коду, уже кое-что изменил к вашему коду, сейчас я над ним работаю.

Edit 2: Внесены изменения в код,Я надеюсь, что это работает.Не забудьте изменить "yourfilepath" в верхней части кода.

1 голос
/ 23 марта 2012

iDroid,

У вас очень сложная ситуация.Всякий раз, когда вы выполняете попиксельные операции, все становится немного громоздким.Итак, несколько небольших оптимизаций являются ключевыми, и я уверен, что многим людям здесь есть что добавить.Я не уверен, какое влияние они окажут на ваш общий процесс, но я знаю, что это общее поведение спасает меня, оптимизируя МНОГО кода.поведение, но будет иметь гораздо более высокие урожаи.

Надеюсь, это поможет,

FuzzicalLogic

1 голос
/ 23 марта 2012

Просто предложение уменьшить цикл for вдвое.Вы должны попробовать с вашими изображениями и посмотреть, работает ли он.

Идея: Исходя из предположения, что следующий пиксель совпадает с текущим, мы анализируем только текущий пиксель и применяем результат как к текущему, так и к следующему пикселю.

Недостаток: у вас есть 50% шанс исказить 1 пиксель.

Пример: Превратить цвет 1 в 3

Оригинал: 1 1 1 1 1 2 2 2 2 2 2 1 1 1

После цикла: 3 3 3 3 3 3 2 2 2 2 2 2 3 3 (Выполнено только 7 циклов. Но цвет 2 смещен на 1 пиксель.)

Используя оригинальную логику, будет выполнено 14 циклов.

for(int x = 0; x < mask.getWidth(); x++){
    for(int y = 0; y < mask.getHeight() - 1; y+=2) { // Change point 1

        g = (mask.getPixel(x,y) & 0x0000FF00) >> 8;
        r = (mask.getPixel(x,y) & 0x00FF0000) >> 16;
        b = (mask.getPixel(x,y) & 0x000000FF);

        if(Math.abs(sR-r) < ANTILAISING_TOLERANCE && Math.abs(sG-g) < ANTILAISING_TOLERANCE && Math.abs(sB-b) < ANTILAISING_TOLERANCE)
            colored.setPixel(x, y, (colored.getPixel(x, y) & 0xFFFF0000));
            colored.setPixel(x, y+1, (colored.getPixel(x, y) & 0xFFFF0000)); // Change point 2
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...