2010-02-17 4 views
0

Я разрабатываю объект Canvas, который использовался для рисования BufferedImage размером 228x262 пикселей.Проблемы с производительностью с Java 2D при рисовании bufferedimages

Это изображение было нарисовано с использованием метода Graphics2D.drawImage (...). Я выполняю обработку цвета на основе пикселя в заданных диапазонах смещения. Образец кода ниже:.

for(int i = frameOffset; i < colorClock; i++) { 
    rgb[i] = new Color(this.colorBK).getRGB(); 
    } 

Где RBG установлен этот BufferedImage я меняющегося в
Проблема заключается в том, что код рисует медленно.

Я создаю изображение, используя GraphicsConfiguration.createCompatibleImage, и я использую двойную буферизацию с помощью стратегии буфера.

Любые огни, пожалуйста?

Thanks on adv.

+0

Под «покраской», вы имеете в виду после преобразования RGB? Или выполняется ли указанное преобразование при каждом тике рендеринга? – jevon

+0

Привет, петля окрашивания возникает после завершения обновления. Сначала меняю цвета на заданные пиксели, а затем Graphics2D.drawImage с новыми цветами пикселей. – Leonardo

+1

Вы пробовали профилировать его? Какую IDE вы используете? У NetBeans встроен профайлер, и я считаю, что есть плагин для Eclipse. –

ответ

0

Не создавайте новый цвет только для того, чтобы извлечь целое число RGB для каждого пикселя в вашем изображении. Единственный конструктор параметров, который я могу найти для Color, - это тот, который принимает int RGB. Не можете ли вы просто использовать colorBK напрямую?

Также, если вы делаете это преобразование на каждой краске, которая будет медленной; вам нужно будет только сделать преобразование один раз.

+0

Привет, обезьяна, спасибо, что ответили. На самом деле, я должен изменить цвет некоторых пикселей после выполнения части кода. Конструктор цветов, который я использую для преобразования, действительно является тем, который принимает int RGB, но я внес некоторые изменения, и теперь я могу использовать его напрямую.Пока getRGB() под капотом делает некоторые сдвиги в битах компонентов цвета, он возвращает другое значение, чем тот, который я передаю конструктору. Но после незначительных изменений кода я теперь могу сделать это прямо. Спасибо. Но, тем не менее, никакого повышения производительности. – Leonardo

+0

@ Leonardo: Единственное «изменение», сделанное этим конструктором, должно сделать альфа-значение полностью непрозрачным: 'value = 0xff000000 | RGB; '. Это можно легко сделать без создания временного объекта. –

+0

Легкий человек, вы правы. Как я уже говорил: «Но после незначительных изменений кода я теперь могу сделать это прямо». Я имел в виду, что мне удалось сделать это без какого-либо временного объекта. Извините за недостаток возможностей выражения. Моя точка зрения заключается в том, что даже без темпов я все еще получаю проблемы с производительностью. Это не большой 262x228 BufferedImage, но это занимает достаточно времени, так как для меня видно, что линии были сжаты во время рисования. Спасибо за ответы. – Leonardo

1

Если вы запускаете цикл каждый раз, когда рисуете изображение, петля может быть узким местом. Существует совершенно ненужное выделение объектов, которое заставит сборщик мусора работать довольно часто.

Я предполагаю, что цветBK является int. Если это так, вы просто создаете и инициализируете объект «Цвет» и просите его вернуть значение rgb, которое назначено массиву rgb. На самом деле происходит то, что вы назначаете значение colorBK в массиве rgb. Таким образом, эквивалентной и более эффективной реализацией будет rgb [i] = colorBK.

Чтобы оптимизировать это, вы можете присвоить значение colorBK конечной локальной переменной. Это позволит избежать повторного ввода значения поля. Таким образом, цикл может выглядеть следующим образом:

final int color = colorBK; 
for(int i = frameOffset; i < colorClock; i++) { 
    rgb[i] = color; 
} 

Чтобы получить еще больше прироста производительности, вы должны думать, что если есть совершенно разные способы сделать это. Поскольку приведенный выше пример просто изменяет некоторые пиксели на определенный цвет, я могу предположить, что это можно сделать с изображением и несколькими fillRects.

Таким образом, вы должны заполнить прямоугольник за изображением нужного цвета (в данном случае colorBK). Если изображение имеет прозрачные пиксели в тех областях, которые были изменены выше, они остаются неизменными в холсте и получают тот же эффект. Это может быть более эффективным, поскольку графические методы лучше оптимизированы и не связаны с использованием большого массива.

+0

И, как указывали другие в этой теме, если цвет постоянный, это нужно сделать только один раз, когда изображение загружается, а не во время каждой краски. – Lauri

+0

Hi Lauri. На самом деле, графические методы должны быть лучше, но я уже пробовал это с fillRects раньше, и это было намного медленнее. Но так как код в то же время значительно отличается от этого времени, я использовал fillRects вместо рисунка BufferedImage, но производительность не изменилась. Хотя, я не пробовал использовать трюк fillRect, и я это проверю. Спасибо. Вероятно, мне нужно переосмыслить всю систему рисования. – Leonardo