Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для мобильных телефонов > Android

Android Разработка игр на платформе Android

Ответ
 
Опции темы
Старый 24.12.2013, 09:35   #1
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Работа с пикселами битовой карты

попробовал применять фильтры и матрицы родными средствами андроид. показалось, что медленно. и тут я сделал глупость. накидал свой обработчик битмапов. теперь отрисовка приведенного в оффтопе примера (поворот картинки на произвольный угол с соответствующим увеличением размеров) на эмуляторе проходит за 9 с лишним секунд! вот это ускорил! понимаю, что дурак, но сам никак не соображу, где я не прав. не подскажете?
// кусочек кода активити для теста
    
ImageView ivMain;

    @
Override
    
protected void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        
setContentView(R.layout.activity_main);
        
ivMain = (ImageViewfindViewById(R.id.ivMain);
        
Bitmap bmp BitmapFactory.decodeResource(getApplicationContext().getResources(),
                
getApplicationContext().getResources().getIdentifier("cvetochek""drawable"getPackageName()));
        
long ms System.currentTimeMillis();
        
Trans t Trans(bmp);
        
t.add_act(Trans.T_ROTATE45);
        
ivMain.setImageBitmap(t.doit());
        
ms System.currentTimeMillis() - ms;
        
Log.d("Trans""time=" ms);
    } 
package ik.puk.tralyalya;

import java.util.ArrayList;
import java.util.Arrays;

import android.graphics.Bitmap;
import android.util.Log;

// класс для БЫСТРОГО (ага, молния, бля!) выполнения нескольких примитивных трансформаций битмапа
// основные функции:
// конструктор Trans(Bitmap bitmap) - создать оъект класса Trans, добавив битмап, который будет преобразовываться
// void add_act(int action, int[] params) - добавить действие с параметрами
// Bitmap doit() - выполнить все действия с битмапом и получить результирующий битмап
public class Trans {
    
    
// битмапы: исходный и результирующий
    
private static int[] bmp null;
    private static 
int[] new_bmp null;
    
    
// размеры битовых карт
    
private static int bmp_w 0;
    private static 
int bmp_h 0;
    private static 
int new_bmp_w 0;
    private static 
int new_bmp_h 0;
    
    public static final 
int default_color 0;
    
    
// типы действий, совершаемых над битмапом
    
public static final int T_NONE 0// ничего не делать
    
public static final int T_RESIZE 1// изменить размер
    
public static final int T_CROP 2// размер полотна (вырезать кусок или добавить края)
    
public static final int T_FREE 3// свободная трансформация по четырем угловым точкам
    
public static final int T_ROTATE 4// повернуть на угол
    
public static final int T_FLIPV 5// отобразить по вертикали
    
public static final int T_FLIPH 6// отобразить по горизонтали
    
public static final int T_OPACITY 7// прозрачность, изменяется только альфа-канал
    
public static final int T_GREY 8// оттенки серого
    
public static final int T_ANDMASK 9// маска. argb &= mask
    
public static final int T_ORMASK 10// маска. argb |= mask
    
public static final int T_XORMASK 11// маска. argb ^= mask
    
public static final int T_INVERT 12//обратить цвета. a = a; r = !r; g = !g; b = !b
    
    // вспомогательный класс для хранения типа действия и параметров  в одной кучке
    
private class Act {
        
int act;
        
int[] params;
        
        public 
Act(int actint[] params) {
            
this.act act;
            
this.params params;
        }
    }
    
    
// список последовательности действий, которые будут производиться над битмапом
    
private static ArrayList<Actactions;
    
    
// конструктор класса. на входе - битмап в виде массива
    
public Trans(Bitmap bitmap) {
        
actions = new ArrayList<Act>();
        
bmp_w bitmap.getWidth();
        
bmp_h bitmap.getHeight();
        
bmp = new int[bmp_w*bmp_h];
        
bitmap.getPixels(bmp0bmp_w00bmp_wbmp_h);
        
bitmap.recycle();
    }

    
// добавить действие без параметров в список
    
public void add_act(int action) {
        
actions.add(new Act(actionnull));
    }
    
    
// добавить действие в список
    
public void add_act(int actionint[] params) {
        
actions.add(new Act(actionparams));
    }
    
    
// добавить действие с одним параметром
    
public void add_act(int actionint angle) {
        
actions.add(new Act(action, new int[]{angle}));
    }

    
// добавить действие с двумя параметрами
    
public void add_act(int actionint wint h) {
        
actions.add(new Act(action, new int[]{wh}));
    }

    
// добавить действие с четырьмя параметрами
    
public void add_act(int actionint xint yint wint h) {
        
actions.add(new Act(action, new int[]{xywh}));
    }

    
// добавить действие с восемью параметрами
    
public void add_act(int actionint x0int y0int x1int y1int x2int y2int x3int y3) {
        
actions.add(new Act(action, new int[]{x0y0x1y1x2y2x3y3}));
    }
    
    
// перенос нового битмапа в старый
    
private static void exchange() {
        
bmp_w new_bmp_w;
        
bmp_h new_bmp_h;
        
bmp new_bmp;
        
new_bmp null;
    }
    
    
// находится ли пиксель в пределах битовой карты?
    
private static boolean in_bmp(int xint y) {
        return ((
>= 0)&&(>= 0)&&(bmp_w)&&(bmp_h));
    }

    
// находится ли пиксель в пределах битовой карты?
    
private static boolean in_new_bmp(int xint y) {
        return ((
>= 0)&&(>= 0)&&(new_bmp_w)&&(new_bmp_h));
    }
    
    
// свободная трансформация
    // на входе координаты четырех углов, по которым нужно растянуть битмап
    
private static void t_free(int n[]) {
        if (
n.length == 8) {
            
double x0 n[0]; double y0 n[1];
            
double x1 n[2]; double y1 n[3];
            
double x2 n[4]; double y2 n[5];
            
double x3 n[6]; double y3 n[7];
            
// new_x = A1*x + B1*x*y + C1*y + x0;
            // new_y = A2*x + B2*x*y + C2*y + y0;
            
new_bmp = new int[bmp_w*bmp_h];
            
Arrays.fill(new_bmpdefault_color);
            
double w bmp_w;
            
double h bmp_h;
            
double A1 = (x1 x0)/w;
            
double A2 = (y1 y0)/w;
            
double C1 = (x3 x0)/h;
            
double C2 = (y3 y0)/h;
            
double B1 = (x2 x3 x1 x0)/w/h;
            
double B2 = (y2 y3 y1 y0)/w/h;
            for (
int y 0hy++) {
                for (
int x 0wx++) {
                    
int new_x = (int)(A1*B1*x*C1*x0);
                    
int new_y = (int)(A2*B2*x*C2*y0);
                    if (
in_bmp(new_xnew_y)) {
                        
new_bmp[new_x new_y*new_bmp_w] = bmp[y*bmp_w];
                    }
                }
            }
            
exchange();
        }
    }

    
// растягивание битмапа
    
private static void t_resize(int[] n) {
        if (
n.length == 2) {
            
new_bmp_w n[0];
            
new_bmp_h n[1];
            
new_bmp = new int[new_bmp_w*new_bmp_h];
            
Arrays.fill(new_bmpdefault_color);
            for (
int y 0new_bmp_hy++) {
                for (
int x 0new_bmp_wx++) {
                    
int xx = (int)(Math.round(x*bmp_w/new_bmp_w));
                    
int yy = (int)(Math.round(y*bmp_h/new_bmp_h));
                    if (
in_bmp(xxyy)) {
                        
new_bmp[y*new_bmp_w] = bmp[xx yy*bmp_w];
                    }
                }
            }
            
exchange();
        }
    }

    
// вырезание куска битмапа (или изменение размера полотна)
    // на входе - новые ширина/высота или координаты нового верхнего левого угла и новые ширина/высота
    
private static void t_crop(int[] n) {
        
int dx 0int dy 0;
        
int new_w 0int new_h 0;
        if ((
n.length == 2)||(n.length == 4)) {
            if (
n.length == 2) {
                
new_w n[0];
                
new_h n[1];
                
dx Math.round((new_w bmp_w)/2);
                
dy Math.round((new_h bmp_h)/2);
            } else {
                
dx n[0];
                
dy n[1];
                
new_w n[2];
                
new_h n[3];
            }
            
new_bmp_w new_w;
            
new_bmp_h new_h;
            
new_bmp = new int[new_w*new_h];
            
Arrays.fill(new_bmpdefault_color);
            for (
int y 0new_bmp_hy++) {
                for (
int x 0new_bmp_wx++) {
                    
int xx dx;
                    
int yy dy;
                    if (
in_bmp(xxyy)) {
                        
new_bmp[y*new_bmp_w] = bmp[xx yy*bmp_w];
                    }
                }
            }
            
exchange();
        }
    }
    
    
// поворот битмапа на угол
    
private static void t_rotate(int n[]) {
        if (
n.length 0) {
            
int a n[0];
            
double sn Math.sin(Math.toRadians(a));
            
double cs Math.cos(Math.toRadians(a));
            
new_bmp_w bmp_w;
            
new_bmp_h bmp_h;
            
            
int xc bmp_w/2;
            
int yc bmp_h/2;
            
int x0 = (int) (Math.cos(Math.toRadians(a))*(bmp_w xc) + Math.sin(Math.toRadians(a))*(bmp_h yc) + xc);
            
int x1 = (int) (Math.cos(Math.toRadians(a))*(-xc) + Math.sin(Math.toRadians(a))*(-yc) + xc);
            
int y0 = (int) (Math.cos(Math.toRadians(a))*(bmp_h yc) - Math.sin(Math.toRadians(a))*(bmp_w xc) + yc);
            
int y1 = (int) (Math.cos(Math.toRadians(a))*(-yc) - Math.sin(Math.toRadians(a))*(-xc) + yc);
            
new_bmp_w = (int) (Math.abs(x1 x0));
            
new_bmp_h = (int) (Math.abs(y1 y0));
            
Log.d("Trans""w=" new_bmp_w);
            
Log.d("Trans""h=" new_bmp_h);

            
t_crop(new int[] {new_bmp_wnew_bmp_h});
            
xc bmp_w/2;
            
yc bmp_h/2;
            
new_bmp = new int[new_bmp_w*new_bmp_h];
            for (
int new_y 0new_y bmp_hnew_y++){
                for (
int new_x 0new_x bmp_wnew_x++) {
                    
int x = (int) ((cs*(new_x xc) + sn*(new_y yc)) + xc);
                    
int y = (int) ((cs*(new_y yc) - sn*(new_x xc)) + yc);
                    if (
in_bmp(xy)&&(in_new_bmp(new_xnew_y))) {
                        
new_bmp[new_x new_y*new_bmp_w] = bmp[y*bmp_w];
                    }
                }
            }
            
exchange();
        }
    }
    
    
// отобразить битмап по горизонтали
    
private static void t_fliph() {
        
new_bmp_w bmp_w;
        
new_bmp_h bmp_h;
        
new_bmp = new int[bmp_w*bmp_h];
        for (
int y 0bmp_hy++) {
            for (
int x 0bmp_wx++) {
                
new_bmp[y*bmp_w] = bmp[bmp_w y*bmp_w];
            }
        }
        
exchange();
    }


    
// отобразить битмап по вертикали
    
private static void t_flipv() {
        
new_bmp_w bmp_w;
        
new_bmp_h bmp_h;
        
new_bmp = new int[bmp_w*bmp_h];
        for (
int y 0bmp_hy++) {
            for (
int x 0bmp_wx++) {
                
new_bmp[y*bmp_w] = bmp[+ (bmp_h 1)*bmp_w];
            }
        }
        
exchange();
    }
    
    
// выполнить все преобразования из списка и вернуть результат в виде битмапа
    
public Bitmap doit() {
        
new_bmp_w bmp_w;
        
new_bmp_h bmp_h;
        
new_bmp = new int[new_bmp_w*new_bmp_h];
        while (
actions.size() > 0) {
            
Act act actions.get(0);
            switch (
act.act) {
                case 
T_RESIZE:
                    
t_resize(act.params);
                    break;
                case 
T_CROP:
                    
t_crop(act.params);
                    break;
                case 
T_FREE:
                    
t_free(act.params);
                    break;
                case 
T_ROTATE:
                    
t_rotate(act.params);
                    break;
                case 
T_FLIPH:
                    
t_fliph();
                    break;
                case 
T_FLIPV:
                    
t_flipv();
                    break;
            }
            
actions.remove(0);
        }
        
new_bmp null;
        return 
Bitmap.createBitmap(bmpbmp_wbmp_hBitmap.Config.ARGB_8888);
    }
    

__________________
to be or not to be - it's not a question!
2b or not 2b = ff
(Offline)
 
Ответить с цитированием
Старый 24.12.2013, 10:16   #2
Romanzes
Разработчик
 
Аватар для Romanzes
 
Регистрация: 05.04.2008
Сообщений: 541
Написано 196 полезных сообщений
(для 637 пользователей)
Ответ: Работа с пикселами битовой карты

Я думаю, если у тебя идет такая интенсивная работа с изображениями - масштабирование, повороты, стоит попробовать OpenGL, причем не напрямую, а какой-нибудь бесплатный открытый движок, рекомендую LibGDX. Гонять туда-сюда битмапы - не вариант.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
barsunduk (24.12.2013)
Старый 24.12.2013, 11:24   #3
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: Работа с пикселами битовой карты

работа не очень интенсивная, как я считал. раз в 100 миллисекунд крутнуть, растянуть 2-4 картинки. и то не всё время, а на время анимации объектов...
додумался проверить только что время работы функций извлечения битмапов. взять/положить один битмап - 800мс. прогнать фильтр по каждой точке - еще секунды полторы-две. пипец. а хотел использовать для работы именно с imageView, чтобы она сама мне результат уже масштабированный как надо на экран выводила (
ок, буду пользоваться движками. тогда и контролы самому придется изобретать, как я понял, да?
---
з.ы.: еще немного тут с Romanzes-ом пообщаюсь - и сам программистом стану)))
__________________
to be or not to be - it's not a question!
2b or not 2b = ff

Последний раз редактировалось barsunduk, 25.12.2013 в 08:10.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 23:07.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com