Sunday 15 August 2010

rgb - How to create X% percent gray color in Java? -



rgb - How to create X% percent gray color in Java? -

suppose want 25% or 31% grayness color in java?

the next code shows

bufferedimage image = new bufferedimage(2, 2, bufferedimage.type_byte_gray); image.setrgb(0, 0, new color(0,0,0).getrgb()); image.setrgb(1, 0, new color(50, 50, 50).getrgb()); image.setrgb(0, 1, new color(100,100,100).getrgb()); image.setrgb(1, 1, new color(255,255,255).getrgb()); raster raster = image.getdata(); double[] info = raster.getpixels(0, 0, raster.getwidth(), raster.getheight(), (double[]) null); system.out.println(arrays.tostring(data));

obvious fact, rgc relates density (?) non linear

[0.0, 8.0, 32.0, 255.0]

so, how create color of given density?

update

i have tried methods, proposed @icza , @hlg , 1 more found me:

double[] data; raster raster; bufferedimage image = new bufferedimage(1, 1, bufferedimage.type_byte_gray); float[] grays = {0, 0.25f, 0.5f, 0.75f, 1}; colorspace linearrgb = colorspace.getinstance(colorspace.cs_linear_rgb); colorspace grayness = colorspace.getinstance(colorspace.cs_gray); color color; int[] rgb; for(int i=0; i<grays.length; ++i) { system.out.println("\n\nshould " + (grays[i]*100) + "% gray"); color = new color(linearrgb, new float[] {grays[i], grays[i], grays[i]}, 1f); image.setrgb(0, 0, color.getrgb()); raster = image.getdata(); info = raster.getpixels(0, 0, 1, 1, (double[]) null); system.out.println("data cs_linear_rgb (hlg method) = " + arrays.tostring(data)); color = new color(gray, new float[] {grays[i]}, 1f); image.setrgb(0, 0, color.getrgb()); raster = image.getdata(); info = raster.getpixels(0, 0, 1, 1, (double[]) null); system.out.println("data cs_gray = " + arrays.tostring(data)); rgb = getrgb(math.round(grays[i]*255)); color = new color(rgb[0], rgb[1], rgb[2]); image.setrgb(0, 0, color.getrgb()); raster = image.getdata(); info = raster.getpixels(0, 0, 1, 1, (double[]) null); system.out.println("data icza method = " + arrays.tostring(data)); }

and gave different results!

should 0.0% grayness info cs_linear_rgb (hlg method) = [0.0] info cs_gray = [0.0] info icza method = [0.0] should 25.0% grayness info cs_linear_rgb (hlg method) = [63.0] info cs_gray = [64.0] info icza method = [36.0] should 50.0% grayness info cs_linear_rgb (hlg method) = [127.0] info cs_gray = [128.0] info icza method = [72.0] should 75.0% grayness info cs_linear_rgb (hlg method) = [190.0] info cs_gray = [192.0] info icza method = [154.0] should 100.0% grayness info cs_linear_rgb (hlg method) = [254.0] info cs_gray = [254.0] info icza method = [255.0]

now wonder 1 correct?

update 2

sorry, gray/white percentage should be, of course, reversed.

the huge differences due gamma encoding in srgb (wikipedia). srgb default color space used in color constructor. if set colors using linear rgb color space instead, gray values not distorted:

colorspace linearrgb = colorspace.getinstance(colorspace.cs_linear_rgb); color grey50 = new color(linearrgb, new float[]{50f/255,50f/255,50f/255}, 1f); color grey100 = new color(linearrgb, new float[]{100f/255,100f/255,100f/255}, 1f); color grey255 = new color(linearrgb, new float[]{1f,1f,1f}, 1f);

however, when setting pixel using color.getrgb , imagebuffer.setrgb, linear gray scale values converted srgb , back. gamma encoded , decoded, yielding rounding errors depending on chosen color space.

these errors can avoided setting raw pixel info behind grayness scale color model directly:

writableraster writable = image.getraster(); writable.setpixel(0,0, new int[]{64});

note, have round percentage values, e.g. 25% can not store 63.75. if need more precision, utilize type_ushort_gray instead of type_byte_gray.

java rgb color-space hsb

No comments:

Post a Comment