ビットマップにレベルを適用する次のアルゴリズム (Android/NDK 用) を作成しました。問題は、SGSIII などの高速なデバイスでは、8MP イメージの場合に最大 4 秒かかることがあるため、非常に遅いことです。また、ARMv6 を搭載したデバイスでは、時間がかかります (10 秒以上)。それを最適化する方法はありますか?
void applyLevels(unsigned int *rgb, const unsigned int width, const unsigned int height, const float exposure, const float brightness, const float contrast, const float saturation)
{
float R, G, B;
unsigned int pixelIndex = 0;
float exposureFactor = powf(2.0f, exposure);
float brightnessFactor = brightness / 10.0f;
float contrastFactor = contrast > 0.0f ? contrast : 0.0f;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
const int pixelValue = buffer[pixelIndex];
R = ((pixelValue & 0xff0000) >> 16) / 255.0f;
G = ((pixelValue & 0xff00) >> 8) / 255.0f;
B = (pixelValue & 0xff) / 255.0f;
// Clamp values
R = R > 1.0f ? 1.0f : R < 0.0f ? 0.0f : R;
G = G > 1.0f ? 1.0f : G < 0.0f ? 0.0f : G;
B = B > 1.0f ? 1.0f : B < 0.0f ? 0.0f : B;
// Exposure
R *= exposureFactor;
G *= exposureFactor;
B *= exposureFactor;
// Contrast
R = (((R - 0.5f) * contrastFactor) + 0.5f);
G = (((G - 0.5f) * contrastFactor) + 0.5f);
B = (((B - 0.5f) * contrastFactor) + 0.5f);
// Saturation
float gray = (R * 0.3f) + (G * 0.59f) + (B * 0.11f);
R = gray * (1.0f - saturation) + R * saturation;
G = gray * (1.0f - saturation) + G * saturation;
B = gray * (1.0f - saturation) + B * saturation;
// Brightness
R += brightnessFactor;
G += brightnessFactor;
B += brightnessFactor;
// Clamp values
R = R > 1.0f ? 1.0f : R < 0.0f ? 0.0f : R;
G = G > 1.0f ? 1.0f : G < 0.0f ? 0.0f : G;
B = B > 1.0f ? 1.0f : B < 0.0f ? 0.0f : B;
// Store new pixel value
R *= 255.0f;
G *= 255.0f;
B *= 255.0f;
buffer[pixelIndex] = ((int)R << 16) | ((int)G << 8) | (int)B;
pixelIndex++;
}
}
}