2010-03-21 3 views
3

Я пишу приложение для Android, которое рисует непосредственно на холсте в событии onDraw в представлении.Рисование на холсте

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

for (int x = 0; x < xMax; x++) { 
    for (int y = 0; y < yMax; y++){ 
    MyColour = CalculateMyPoint(x, y); 
    canvas.drawPoint(x, y, MyColour); 
    } 
} 

Проблема здесь состоит в том, что это занимает много времени, чтобы рисовать, как обычной CalculateMyPoint является довольно дорогим метод.

Есть ли более эффективный способ рисования на холсте, например, следует ли рисовать растровое изображение, а затем рисовать весь растровый рисунок на холсте в событии onDraw? Или, может быть, оценить мои цвета и заполнить массив, который метод onDraw может использовать для рисования холста?

Пользователи моего приложения смогут изменять параметры, которые влияют на рисунок на холсте. На данный момент это невероятно медленно.

+0

Что делает CalculateMyPoint так долго работать? – Adam

+0

У меня есть разумно вовлеченный расчет, чтобы рассчитать цвет, который будет использоваться для любого заданного пикселя. Мне просто интересно, лучше ли вычислять цвет для каждого пикселя else, а не в событии onDraw в представлении. – Mattl

+0

Нужно ли рисовать каждый пиксель отдельно? Поскольку это более 400 тыс. Пикселей на Droid или nexus, и я чувствую, что есть больше возможностей для оптимизации количества вызовов CalculateMyPoint, чем во время выполнения. – jqpubliq

ответ

5

Как люди указали, если CalculateMyPixel() стоит дорого, то, что называется 150 000 (HVGA) или 384,00 раз (WVGA), просто убьет вас.

Кроме того, пытаясь нарисовать ваш пользовательский интерфейс как отдельные пиксели через canvas.drawPoint(), каждый раз, когда есть обновление, это всего лишь наименее эффективный способ сделать это.

Если вы рисуете отдельные пиксели, вы почти наверняка хотите иметь какой-то экранный растровый рисунок, содержащий пиксели, которые вы рисуете с помощью простого Canvas.drawBitmap().

Тогда вы можете выбрать лучший способ управлять этим растровым изображением. Простейшим является просто создать объект Bitmap нужного размера и использовать там API-интерфейсы для его заполнения.

В качестве альтернативы существует версия drawBitmap(), которая берет массив целых чисел, поэтому вы можете заполнить его в непосредственно с любыми значениями, которые вы хотите, избегая вызова метода для каждого пикселя.

Теперь вы можете перенести вычисление пикселей из метода onDraw(), который должен быть быстрым, чтобы иметь гибкий пользовательский интерфейс и заполнить ваши пиксели в другом месте. Возможно, вы вычислите их один раз во время инициализации. Возможно, вы их вычисляете и выполняете выборочные обновления только тех частей, которые были изменены до вызова invalidate() (например, пиксели из (0,0) - (10, 10) изменились, поэтому возьмите текущее растровое изображение и просто измените эту область). Если вычислительные пиксели на самом деле просто слишком медленны, вы, вероятно, захотите создать отдельный поток для выполнения этой работы (обновление растрового изображения с новыми пикселями, затем postInvalidate() в пользовательском интерфейсе, чтобы получить их рисование).

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

+0

Спасибо, я думаю, это все здравый смысл.
На данный момент для инициализации приложения с кодом в моей процедуре OnDraw требуется около 1 минуты, что-то более 1 секунды, вероятно, неприемлемо.
Этот вызов может инициализировать мой битмап с массивом пикселей мне нужно:
публичный статический Bitmap CreateBitmap (ИНТ [] цвета, ширина INT, INT высота, Bitmap.Config конфигурации)
Это также верно, что я на самом деле не требуется разрешение WVGA, поэтому я буду экспериментировать с масштабированием.
Mattl

+0

Я провел вечер после этих советов и получил рендеринг от почти минуты до 3 секунд! Думаю, я смогу еще больше сбрить, оптимизируя дальше. Еще раз спасибо hackbod. – Mattl

+1

вы можете показать пример улучшенного кода, пожалуйста. –

Смежные вопросы