Это критически важная часть моего приложения для Android, и я использую NDK (c) для обработки большого массива растровых изображений.
int blender(const char* blendMode, int c1, int c2, int amount){
int sob, sog, sor, soa, dsr, dsg, dsb, dsa = 0;
dsr = Argb_GetRed(c1);
dsg = Argb_GetGreen(c1);
dsb = Argb_GetBlue(c1);
dsa = Argb_GetAlpha(c1);
sor = Argb_GetRed(c2);
sog = Argb_GetGreen(c2);
sob = Argb_GetBlue(c2);
soa = Argb_GetAlpha(c2);
int src_alpha, mix_alpha, dst_alpha;
src_alpha = soa * ((255 * amount) / 100) >> 8;
if (!strcmp(blendMode, "normal")) {
PSD_BLEND_NORMAL(dsr, sor, mix_alpha);
PSD_BLEND_NORMAL(dsg, sog, mix_alpha);
PSD_BLEND_NORMAL(dsb, sob, mix_alpha);
}
else if (!strcmp(blendMode, "exclusion")) {
mix_alpha = soa / 255;
//.... it's not always just the 3 macros
PSD_BLEND_EXCLUSION(dsr, sor, mix_alpha);
PSD_BLEND_EXCLUSION(dsg, sog, mix_alpha);
PSD_BLEND_EXCLUSION(dsb, sob, mix_alpha);
}
~~~~~~~~~ X 20 or so blend modes ~~~~~~~~~~~~
}
В настоящее время он запускает эту функцию блендера для каждого пикселя и выполняет переключение (явно неэффективно).
Кроме того, он должен принимать исходную команду в виде строки (из json и передавать через java)
Я могу придумать пару способов сделать его более эффективным, но все они включают в себя написание двух гигантских операторов switch. Я бы предпочел использовать 1 оператор переключения или поиск, если это возможно
Спасибо!
1 ответ
Довольно неприятная проблема, но у меня есть "хакерская" идея.
Если имена 'blendMode' выбраны правильно, вы можете сравнить только первые две (или три) буквы строк. Если есть несколько строк с одинаковыми первыми буквами, вы можете сделать особый случай и сравнить первую и третью букву и так далее.
Этот прием сделает код намного быстрее, чем постоянный вызов strcmp(). Также может помочь встраивание функции сравнения.
Вот код:
/* compares first two letters of the string */
inline int fast_cmp(const char *mode, const char *cmp) {
return (mode[0] == cmp[0] && mode[1] == cmp[1]) ? 1 : 0;
}
if( fast_cmp(blendMode, "no") ); /* for "normal" */
if( fast_cmp(blendMode, "ex") ); /* for "exclusion" */
В действии: http://ideone.com/OiXS0.
Конечно, сравнения могут быть записаны непосредственно в операторах if/else, но это может привести к путанице. Это можно исправить с помощью небольшого и изящного макроса:
#define FAST_CMP(x, y) x[0] == y[0] && x[1] == y[1]
А вот макрос в действии: http://ideone.com/NQFwW
Эта версия макроса, пожалуй, самый быстрый способ сделать сравнение.
Похожие вопросы
Новые вопросы
android
Android — это мобильная операционная система Google, используемая для программирования или разработки цифровых устройств (смартфонов, планшетов, автомобилей, телевизоров, одежды, очков, IoT). Для тем, связанных с Android, используйте теги, специфичные для Android, такие как android-intent, android-activity, android-adapter и т. д. Для вопросов, отличных от разработки или программирования, но связанных с Android framework, используйте эту ссылку: https://android .stackexchange.com.