Increasing intensity of RGB - android

I am stuck in a problem and dont know where to look at.
I need to increase intensity of particular color in image, like R, G, or Blue.
When I am doing that, certain colors are not rendering properly.
Below is the image that I took for testing:
Now when I increase like Green color:
A = Color.alpha(p);
R = Color.red(p);
G = (int)(Color.green(p)*1.2);
B = Color.blue(p);
This is what I get:
What can be the solution to fix those Pink patches.
Thanks

Ty clamping the values so that they don't go over 255. Like this:
A = Color.alpha(p);
R = Color.red(p);
G = Math.min((int)(Color.green(p)*1.2), 255);
B = Color.blue(p);

Related

Convert all colors other than a particular color in a bitmap to white

I am using tess-two library and I wish to convert all the colors other than black in my image to white (Black will be text). Thus making it easier for the tess-two to read the text. I have tried various methods but they are taking too much time as they convert pixel by pixel. Is there a way to achieve this using canvas or anything that give results faster.
UPDATE
Another problem that came up with this algorithm is that printer doesn't print with the same BLACK and White as in android. So the algorithm converts the whole picture to white.
Pixel by pixel method that I am currently using.
binarizedImage = convertToMutable(cropped);// the bitmap is made mutable
int width = binarizedImage.getWidth();
int height = binarizedImage.getHeight();
int[] pixels = new int[width * height];
binarizedImage.getPixels(pixels, 0, width, 0, 0, width, height);
for(int i=0;i<binarizedImage.getWidth();i++) {
for(int c=0;c<binarizedImage.getHeight();c++) {
int pixel = binarizedImage.getPixel(i, c);
if(!(pixel == Color.BLACK || pixel == Color.WHITE))
{
int index = c * width + i;
pixels[index] = Color.WHITE;
binarizedImage.setPixels(pixels, 0, width, 0, 0, width, height);
}
}
}
Per, Rishabh's comment. Use a color matrix. Since black is black and is RGB(0,0,0,255), it's immune to multiplications. So if you multiply everything by 255 in all channels everything will exceed the limit and get crimped to white, except for black which will stay black.
ColorMatrix bc = new ColorMatrix(new float[] {
255, 255, 255, 0, 0,
255, 255, 255, 0, 0,
255, 255, 255, 0, 0,
0, 0, 0, 1, 0,
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(bc);
paint.setColorFilter(filter);
You can use that paint to paint that bitmap in only-black-stays-black colormatrix filter glory.
Note: This is a quick and awesome trick, but, it will ONLY work for black. While it's perfect for your use and will turn that lengthy op into something that is instant, it does not actually conform to the title question of "a particular color" my algorithm works in any color you want, so long as it is black.
Though #Tatarize answer was perfect I was having troubles reading a printed image as its not always jet black.
This algorithm which i found on stack overflow works great, it actually checks whether the particular pixel is closer to black or white and converts the pixel to the closest color. Hence providing binarization with range. (https://stackoverflow.com/a/16534187/3710223).
What I am doing now is keeping the unwanted areas in light colors while text in black. This algorithm gives binarized image in approximately 20-35 sec. Still not that fast but efficient.
private static boolean shouldBeBlack(int pixel) {
int alpha = Color.alpha(pixel);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
if(alpha == 0x00) //if this pixel is transparent let me use TRASNPARENT_IS_BLACK
return TRASNPARENT_IS_BLACK;
// distance from the white extreme
double distanceFromWhite = Math.sqrt(Math.pow(0xff - redValue, 2) + Math.pow(0xff - blueValue, 2) + Math.pow(0xff - greenValue, 2));
// distance from the black extreme
double distanceFromBlack = Math.sqrt(Math.pow(0x00 - redValue, 2) + Math.pow(0x00 - blueValue, 2) + Math.pow(0x00 - greenValue, 2));
// distance between the extremes
double distance = distanceFromBlack + distanceFromWhite;
return ((distanceFromWhite/distance)>SPACE_BREAKING_POINT);
}
If the return value is true then we convert the pixel to black else we convert it to white.
I know there can be better/faster answers and more answers are welcomed :)
Same thing but done in renderscript, times about 60-100ms. You won't even notice the delay.
Bitmap blackbitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());
RenderScript mRS = RenderScript.create(TouchEmbroidery.activity);
ScriptC_blackcheck script = new ScriptC_blackcheck(mRS);
Allocation allocationRaster0 = Allocation.createFromBitmap(
mRS,
bitmap,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT
);
Allocation allocationRaster1 = Allocation.createTyped(mRS, allocationRaster0.getType());
script.forEach_root(allocationRaster0, allocationRaster1);
allocationRaster1.copyTo(blackbitmap);
Does the allocation, uses renderscript to write out the data to blackbitmap.
#pragma version(1)
#pragma rs java_package_name(<YOUR PACKAGENAME GOES HERE>)
void root(const uchar4 *v_in, uchar4 *v_out) {
uint32_t value = (v_in->r * v_in->r);
value = value + (v_in->g * v_in->g);
value = value + (v_in->b * v_in->b);
if (value > 1200) {
v_out->r = 255;
v_out->g = 255;
v_out->b = 255;
}
else {
v_out->r = 0;
v_out->g = 0;
v_out->b = 0;
}
v_out->a = 0xFF;
}
Note the 1200 is just the threshold I used, should be all three components less than 20 (or, like 0, 0, sqrt(1200) aka (~34)). You can set the 1200 limit up or down accordingly.
And the build gradle needs Renderscript:
renderscriptTargetApi 22
Last few things of the build tools claims to have fixed a bunch of the renderscript headaches. So it might be perfectly reasonable to do this kind of stuff in mission critical places like yours. 20 seconds is too long to wait, 60 milliseconds is not.

how to create a CMYK image from a RGB BITMAP in android

just like the title of the question, i want to ask how to create a CMYK image when i have a RGB image as a bitmap.
I had reads question that generate the CMYK value from RGB value just like this code
public static int[] rgbToCmyk(int red, int green, int blue)
{
int black = Math.min(Math.min(255 - red, 255 - green), 255 - blue);
if (black!=255) {
int cyan = (255-red-black)/(255-black);
int magenta = (255-green-black)/(255-black);
int yellow = (255-blue-black)/(255-black);
return new int[] {cyan,magenta,yellow,black};
} else {
int cyan = 255 - red;
int magenta = 255 - green;
int yellow = 255 - blue;
return new int[] {cyan,magenta,yellow,black};
}
}
but, after i have the CMYK value i still don't understand where to place the value just like Bitmap.setBitmap() on android.
as i know the setBitmap function use the RGB value, not CMYK value...
there are a way to change the image color type to CMYK in android?
I'm a newbie in android, correct me if I wrong..
The best thing is a library call to convert the format. Try android-lib-magick, described in the Stack Overflow question Android CMYK mode.

Color detection in a static image - OpenCV Android

I have an image with four squares red, green, blue and yellow. I need to get the rgb values of each squares. I'm able to get the rgb of the whole image, but i want it for a specific section.
The image which i am going to get will be from the camera and stored onto the SDCard
I don't know if I understand you exactly, but here it comes.
You need to create BufferedImage object to get RGB value:
File f = new File(yourFilePath);
BufferedImage img = ImageIO.read(f);
You can get RGB Color values from the image from then. You have 4 squares; to check their RGB values, you can check the corner pixels' RGB values:
Color leftTop = new Color(img.getRGB(0, 0));
Color rightTop = new Color(img.getRGB(img.getWidth - 1, 0));
Color leftBottom = new Color(img.getRGB(0, img.getHeight - 1));
Color rightBottom = new Color(img.getRGB(img.getWidth - 1, img.getHeight - 1));
After that it's easy to get red, green and blue values individually:
int red = leftTop.getRed();
int green = leftTop.getGreen();
int blue = leftTop.getBlue();
EDIT:
I'm really sorry, I didn't see it's for Android. As you said, Android doesn't have ImageIO class. To accomplish the task in Android, first initialize the image:
Bitmap img = BitmapFactory.decodeFile(yourFilePath);
From then the operation is pretty much the same:
int leftTop = img.getPixel(0, 0);
...
int red = Color.red(pixel);
int blue = Color.blue(pixel);
int green = Color.green(pixel);
Use this to crop your image.
Now to detect the color of the image take a pixel from the square and detect it's color with this.
After finding the RGB value use a simple conditional statement to see if the square is red blue or green.
I got it this way
int topLeftIndex = squareImage.getPixel(0, 0);
int R1 = (topLeftIndex >> 16) & 0xff;
int G1 = (topLeftIndex >> 8) & 0xff;
int B1 = topLeftIndex & 0xff;
and same way with
int bottomLeftIndex=squareImage.getPixel(0, picHeight - 1);
int topRightIndex=squareImage.getPixel(picWidth -1 , 0);
int bottomRightIndex=squareImage.getPixel(picWidth -1, picHieght - 1);

how to mix two color with different percent

i have two color and a View component. color one is background of my component. i will change my background Color to color two. but not suddenly. change similar a animation. for example:
second 1 : 90% color1 + 10% color2
second 1 : 80% color1 + 20% color2
......
second 1 : 10% color1 + 90% color2
second 1 : 0% color1 + 100% color2
of course i try it :
percent=100;
while (percent>=0) {
color = (color1*precent)+(color2*(100-percent));
percent-=10;
}
but this is a bad idea.the result is disappointing.
is there any solution for this target.
thanks.
You didn't clearly say why the result is disappointing, so I'm assuming it means the color transition you get is not as good you expected it to be.
Your general approach seems right, maybe you are just missing some detail so I will rewrite it in different terms. Let color1 and color2 be triples (R, G, B) where each of R, G, B is in range [0, 1]. If that is not the case, divide by 255 if that is the limit in your situation, and later multiply again by 255. Let s be the number of steps to transition from color1 to color2, here I'm including in s the initial frame with color1 but not the final frame with color2. At step k, you have a value p such that p = (s - k)/s. With p you obtain the color in frame k by doing color = p * color1 + (1 - p) * color2. Now you may want to multiply color by 255.
A pseudocode for this description is:
color1 = (R1, G1, B1)
color2 = (R2, G2, B2)
s = N
for k = 0 to s: # s + 1 steps, according to the description
p = (s - k) / s
color = (p * color1) + ((1 - p) * color2)
Note that at k = 0 you have only color1, and at k = s you get only color2. As you see, it is similar to what you posted with more details. Note that here I'm multiplying each of R, G, B by p.
Here are some examples transitioning from a yellow to some blue color, steps = 10, 25, 500 respectively.

android Bitmap getPixel

I need to get the color of a pixel in order to compare it with a color from my color.xml file, but all values are negative and this comparison will always return a false result. How to get the proper color value? This color may be transparent. I've read this but I need an answer, not a link to theory.
bmp.getPixel(n.x, n.y) is returning zero when I'm expecting to return a propper value for color #00FFFFFF
Thanks
You could do something like this:
int pixel = Color.RED; //bmp.getPixel(n.x, n.y);
int a = Color.alpha(pixel);
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
String color = String.format("#%02X%02X%02X%02X", a, r, g, b); //#FFFF0000 for RED color
but instead of Color.RED you can put your bmp.getPixel(...) method.
Hope that helps
Best Regards

Categories

Resources