renderscriptTargetApi - Specifies the bytecode version to be generated. We recommend you set this value to the lowest API level able to provide all the functionality you are using and set renderscriptSupportModeEnabled to true. Valid values for this setting are any integer value from 11 to the most recently released API level. If your minimum SDK version specified in your application manifest is set to a different value, that value is ignored and the target value in the build file is used to set the minimum SDK version.
renderscriptSupportModeEnabled - Specifies that the generated bytecode should fall back to a compatible version if the device it is running on does not support the target version.
#pragma version(1) #pragma rs_fp_relaxed #pragma rs java_package_name(com.example.q.renderscriptexample) #include"rs_debug.rsh" int32_t histo[256]; float remapArray[256]; int size; //Method to keep the result between 0 and 1 staticfloatbound(float val){ float m = fmax(0.0f, val); return fmin(1.0f, m); } uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) { //Convert input uchar4 to float4 float4 f4 = rsUnpackColor8888(in); //Get YUV channels values float Y = 0.299f * f4.r + 0.587f * f4.g + 0.114f * f4.b; float U = ((0.492f * (f4.b - Y))+1)/2; float V = ((0.877f * (f4.r - Y))+1)/2; //Get Y value between 0 and 255 (included) int32_t val = Y * 255; //Increment histogram for that value rsAtomicInc(&histo[val]); //Put the values in the output uchar4, note that we keep the alpha value return rsPackColorTo8888(Y, U, V, f4.a); } uchar4 __attribute__((kernel)) remaptoRGB(uchar4 in, uint32_t x, uint32_t y) { //Convert input uchar4 to float4 float4 f4 = rsUnpackColor8888(in); //Get Y value float Y = f4.r; //Get Y value between 0 and 255 (included) int32_t val = Y * 255; //Get Y new value in the map array Y = remapArray[val]; //Get value for U and V channel (back to their original values) float U = (2*f4.g)-1; float V = (2*f4.b)-1; //Compute values for red, green and blue channels float red = bound(Y + 1.14f * V); float green = bound(Y - 0.395f * U - 0.581f * V); float blue = bound(Y + 2.033f * U); //Put the values in the output uchar4 return rsPackColorTo8888(red, green, blue, f4.a); } voidinit(){ //init the array with zeros for (int i = 0; i < 256; i++) { histo[i] = 0; remapArray[i] = 0.0f; } } voidcreateRemapArray(){ //create map for y float sum = 0; for (int i = 0; i < 256; i++) { sum += histo[i]; remapArray[i] = sum / (size); } }
publicstatic Bitmap histogramEqualization(Bitmap image, Context context){ //Get image size int width = image.getWidth(); int height = image.getHeight(); //Create new bitmap Bitmap res = image.copy(image.getConfig(), true); //Create renderscript RenderScript rs = RenderScript.create(context); //Create allocation from Bitmap Allocation allocationA = Allocation.createFromBitmap(rs, res); //Create allocation with same type Allocation allocationB = Allocation.createTyped(rs, allocationA.getType()); //Create script from rs file. ScriptC_histEq histEqScript = new ScriptC_histEq(rs); //Set size in script histEqScript.set_size(width*height); //Call the first kernel. histEqScript.forEach_root(allocationA, allocationB); //Call the rs method to compute the remap array histEqScript.invoke_createRemapArray(); //Call the second kernel histEqScript.forEach_remaptoRGB(allocationB, allocationA); //Copy script result into bitmap allocationA.copyTo(res); //Destroy everything to free memory allocationA.destroy(); allocationB.destroy(); histEqScript.destroy(); rs.destroy(); return res; }