JNIEXPORT void JNICALL Java_jp_dego_sample_ipcv_MainActivity_checkColorSpace(JNIEnv *env, jobject obj, jobject bmp) { AndroidBitmapInfo info; void* pixels; // Bitmapの情報を取得 if (AndroidBitmap_getInfo(env, bmp, &info) < 0) return; // Bitmapのフォーマットをチェック if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) return; // Bitmapをロック if (AndroidBitmap_lockPixels(env, bmp, &pixels) < 0) return; int i, j; jint *p = pixels; for (j = 0; j < info.height; j++) { for (i = 0; i < info.width; i++) { ARGB argb = {0, 0, 0, 0}; argb.red = getR(p[j * info.width + i]); argb.green = getG(p[j * info.width + i]); argb.blue = getB(p[j * info.width + i]); XYZ xyz; // LUV luv; // RGBtoXYZ(&argb, &xyz); // XYZtoLUV(&xyz, &luv); // LUVtoXYZ(&luv, &xyz); // XYZtoRGB(&xyz, &argb); LAB lab; RGBtoXYZ(&argb, &xyz); XYZtoLAB(&xyz, &lab); LABtoXYZ(&lab, &xyz); XYZtoRGB(&xyz, &argb); p[j * info.width + i] = createColorFromARGB(argb); } } }
void convert(unsigned char *buf, int width, int height, int de) { double angle_chroma[360]; double angle_hue[360]; double angle_hue2[360]; double minchroma = 999; double maxchroma = 0; { int i; for (i = 0; i < 360; i++) { angle_chroma[i] = 9999; } double f; for (f = 0; f < 360; f += .25) { angle_hue[(int) ((angletohue(f) - angletohue(0)) / (angletohue(360) - angletohue(0)) * 360)] = f; angle_hue2[(int) f] = ((angletohue(f) - angletohue(0)) / (angletohue(360) - angletohue(0)) * 360); } double a; for (a = -80; a <= 80; a += .1) { int dir; for (dir = -1; dir <= 1; dir += 2) { double b = dir * 335.582 * exp(- a * a / (2 * 15.5723 * 15.5723)) / (15.5723 * sqrt(2 * M_PI)); double h = atan2(b, a); double c = sqrt(a * a + b * b); h -= 0.075; if (h < 0) { h += 2 * M_PI; } h = floor(h * 180 / M_PI); if (c < angle_chroma[(int) h]) { angle_chroma[(int) h] = c; } } } for (i = 0; i < 360; i++) { if (angle_chroma[i] < minchroma) { minchroma = angle_chroma[i]; } if (angle_chroma[i] > maxchroma) { maxchroma = angle_chroma[i]; } } } int *buf2 = malloc(width * height * 4 * sizeof(int)); int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int r = buf[(y * width + x) * 4 + 0]; int g = buf[(y * width + x) * 4 + 1]; int b = buf[(y * width + x) * 4 + 2]; double X, Y, Z; double L, A, B; double C, H; RGBtoXYZ(r, g, b, &X, &Y, &Z); XYZtoLAB(X, Y, Z, &L, &A, &B); LABtoLCH(L, A, B, &L, &C, &H); if (H < 0) { H += 2 * M_PI; } if (de) { // desaturate C = C * minchroma / angle_chroma[(int) (H * 180 / M_PI)]; // shift hue int hh = (int) (H * 180 / M_PI + 720) % 360; H = angle_hue2[hh] * M_PI / 180; } else { // shift hue int hh = (int) (H * 180 / M_PI + 720) % 360; H = angle_hue[hh] * M_PI / 180; // resaturate C = C / minchroma * angle_chroma[(int) (H * 180 / M_PI)]; C *= minchroma / maxchroma; } LCHtoLAB(L, C, H, &L, &A, &B); LABtoXYZ(L, A, B, &X, &Y, &Z); XYZtoRGB(X, Y, Z, &r, &g, &b); buf2[(y * width + x) * 4 + 0] = r; buf2[(y * width + x) * 4 + 1] = g; buf2[(y * width + x) * 4 + 2] = b; } } int max = 0; for (x = 0; x < width * height; x++) { int i; for (i = 0; i < 3; i++) { if (buf2[x * 4 + i] > max) { max = buf2[x * 4 + i]; } } } for (x = 0; x < width * height; x++) { int i; for (i = 0; i < 3; i++) { buf[x * 4 + i] = buf2[x * 4 + i] * 255 / max; if (buf2[x * 4 + i] < 0) { buf[x * 4 + i] = 0; } } } }