Imagick ALPHA vs OPACITY - imagemagick

While developping color-extractor I stumbled across a quirk with Imagick. I confirmed the issue with a single black transparent pixel image. Under Gimp this black is shown as 75% opaque so I guess its alpha/transparency is 25%.
When I run getColorValue(\Imagick::COLOR_OPACITY) I get roughly 0.25 whereas I get about 0.75 with getColorValue(\Imagick::COLOR_ALPHA) so the exact opposite of what I expected.
Is this an issue about Imagick (I'm using php-imagick 3.4.3-1 and ImageMagick 6.9.7-9) or am I inverting concepts of opacity and transparency?

Not a quirk, but by design. For the most part, opacity & alpha share the same data channel, and the context of the image format / coder implements the correct value. And I stress context is key.
Is this an issue about Imagick [..] or am I inverting concepts of opacity and transparency?
Let's take a look at how the two are implemented.
PixelGetOpacityQuantum
return(ClampToQuantum(wand->pixel.opacity));
PixelGetAlphaQuantum
return(QuantumRange-ClampToQuantum(wand->pixel.opacity));
As you can see, both return the same data bonded between 0 and Quantum limit.
The PixelGetOpacityQuantum returns the exact data-value, but PixelGetAlphaQuantum adjusts/inverts to what we would expect in popular color formats/specs. It's all context!

Related

How to do Water color painting in iOS using CoreGraphics? [duplicate]

I have been working with OpenGL in iOS, and setting the colors with glColor4f(r,g,b,a) and then drawing my own color on a white UIImageView. I basically have a brush, which is then moved around my user's touch, and then it paints the color onto the canvas. But this color needs to be water paint (like smudged color)
Does anyone understand/knows how to get a water color like this app does, and how the background UIImageView has a texture on it?
https://itunes.apple.com/us/app/hello-watercolor/id539414526?mt=8
or checkout water paint in this. http://www.fiftythree.com/paper
I created a bounty on this as I am really having a hard time to grasp how to derive such smooth flowing colors out of the normal colors. Even if you guys point me in the right direction, or to some sample code on how I can get the effect of water-paint, it would be really helpful ^_^
And as a bonus, it would be also be helpful if you can point out to me how to get canvas on which it is painted on looks realistic, and blended with the paint? Does Blending/GLSL have to do with any of this?
Is there any sample project on this?
If you are still struggling with the basics of getting realistic looking water colors working, you may want to experiment/prototype in photoshop first.
http://www.zoepiel.com/tutorials/watercolor/ shows some very effective tricks for creating watercolor images with simple tools.
The most interesting one is to multiply a group of watercolor layers with a greyscale watercolor paper image. The texture of the paper makes some parts remain white, and other parts saturate with color, just like real watercolor.
Each layer remains 'wet' in the sense that the colors within it blend, but the layers are 'dry' with respect to each other.
She also explains some of her brush and blur settings and shows what they do.
Once you can produce the desired effect in photoshop, you'll have clear specifications of what you want to do and you'll be quite a bit closer to programming it out.
Looking at the examples you posted, it looks like they are using a simple Gaussian Blur with a radius of double your brush size. This may be an incomplete solution, but it's at least the first level.

RMagick - Adjust Brightness?

Does anyone know how to adjust the brightness of an image using RMagick? Rmagick has a number of different functions available, including ones to adjust levels and the hue/brightness/saturation levels, but I need to adjust the old-fashioned brightness/contrast levels.
There are custom functions for me to individually adjust each color channel (RGBA), but I'm not sure how to use levels to adjust the overall brightness. Messing with the different channels has yielded images that are color-altered. On GIMP, in the levels menu, the desired functionality I want is under 'Output Levels'. By dragging this below 255, I can achieve a 'darkening' effect. Is there some kind of equivalent in RMagick to control Output Levels? I don't see a channel for it.
Examples:
THIS IS ORIGINAL IMAGE:
THIS IS WHAT I WANT:
THIS IS WHAT HAPPENS WHEN I ADJUST LIGHTNESS (Rmagick's Modulate)
I think this should do what you need.
img = Magick::Image.read('bT9xc.png')
img.first.level(-Magick::QuantumRange * 0.25, Magick::QuantumRange * 1.25, 1.0).write('out.png')
This sets the black point and the white point 'further away' from the range found in the image, which has the effect of making the brightest white in the source image darker, and the darkest black in the source image lighter.
If you want to make it darker overall, just increase the second factor to Magick::QuantumRange * 1.5 or higher.
I think you can use the modulate method: http://www.imagemagick.org/RMagick/doc/image2.html#modulate
So to increase the brightness by 50% it would be something like:
img.modulate(1.5)

Render water-paint in iOS

I have been working with OpenGL in iOS, and setting the colors with glColor4f(r,g,b,a) and then drawing my own color on a white UIImageView. I basically have a brush, which is then moved around my user's touch, and then it paints the color onto the canvas. But this color needs to be water paint (like smudged color)
Does anyone understand/knows how to get a water color like this app does, and how the background UIImageView has a texture on it?
https://itunes.apple.com/us/app/hello-watercolor/id539414526?mt=8
or checkout water paint in this. http://www.fiftythree.com/paper
I created a bounty on this as I am really having a hard time to grasp how to derive such smooth flowing colors out of the normal colors. Even if you guys point me in the right direction, or to some sample code on how I can get the effect of water-paint, it would be really helpful ^_^
And as a bonus, it would be also be helpful if you can point out to me how to get canvas on which it is painted on looks realistic, and blended with the paint? Does Blending/GLSL have to do with any of this?
Is there any sample project on this?
If you are still struggling with the basics of getting realistic looking water colors working, you may want to experiment/prototype in photoshop first.
http://www.zoepiel.com/tutorials/watercolor/ shows some very effective tricks for creating watercolor images with simple tools.
The most interesting one is to multiply a group of watercolor layers with a greyscale watercolor paper image. The texture of the paper makes some parts remain white, and other parts saturate with color, just like real watercolor.
Each layer remains 'wet' in the sense that the colors within it blend, but the layers are 'dry' with respect to each other.
She also explains some of her brush and blur settings and shows what they do.
Once you can produce the desired effect in photoshop, you'll have clear specifications of what you want to do and you'll be quite a bit closer to programming it out.
Looking at the examples you posted, it looks like they are using a simple Gaussian Blur with a radius of double your brush size. This may be an incomplete solution, but it's at least the first level.

flood fill performance issue on iPad

I am using 4-Way floodfill algorithm.
I have a transparent image with black out line.
That is staring point image(without color).
And after filling the color in this image it look like this
Please help me and let me know what can i do for proper fill.
I used and implemented myself FloodFill in other projects and the algorithm goes trough the whole draw, looking for closed spaces and then draw inside (or outside) them.
Your problem happens with every tool in the world that fills a draw, and the problem is the same, the spaces are not 100% closed.
The floodfill algorithm goes pixel by pixel and when it detect a black pixel, it stops. For example, the arm of the scuba driver is not thick enough or it has holes on it, and the flood fill algorithm manages to go trough it and not detect it as an empty space.
Nobody here can tell you why unless we take your project and analyse it, so the best I can offer is a guideline about where your error could be.
I tried the code with an image that has a very precise defined border around it (from here) and it seems to work OK with that image. I suggest perhaps that if you zoom into your image that there is some grey aliasing around the edges which won't get filled. Perhaps the algorithm has a threshold function that can be tweaked?
Try setting the andTolerance value (I tried 4 which seemed to improve my example).
//Call function to flood fill and get new image with filled color
UIImage *image1 = [self.image floodFillFromPoint:tpoint withColor:newcolor andTolerance:4];

What processing steps should I use to clean photos of line drawings?

My usual method of 100% contrast and some brightness adjusting to tweak the cutoff point usually works reasonably well to clean up photos of small sub-circuits or equations for posting on E&R.SE, however sometimes it's not quite that great, like with this image:
What other methods besides contrast (or instead of) can I use to give me a more consistent output?
I'm expecting a fairly general answer, but I'll probably implement it in a script (that I can just dump files into) using ImageMagick and/or PIL (Python) so if you have anything specific to them it would be welcome.
Ideally a better source image would be nice, but I occasionally use this on other folk's images to add some polish.
The first step is to equalize the illumination differences in the image while taking into account the white balance issues. The theory here is that the brightest part of the image within a limited area represents white. By blurring the image beforehand we eliminate the influence of noise in the image.
from PIL import Image
from PIL import ImageFilter
im = Image.open(r'c:\temp\temp.png')
white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(15))
The next step is to create a grey-scale image from the RGB input. By scaling to the white point we correct for white balance issues. By taking the max of R,G,B we de-emphasize any color that isn't a pure grey such as the blue lines of the grid. The first line of code presented here is a dummy, to create an image of the correct size and format.
grey = im.convert('L')
width,height = im.size
impix = im.load()
whitepix = white.load()
greypix = grey.load()
for y in range(height):
for x in range(width):
greypix[x,y] = min(255, max(255 * impix[x,y][0] / whitepix[x,y][0], 255 * impix[x,y][1] / whitepix[x,y][1], 255 * impix[x,y][2] / whitepix[x,y][2]))
The result of these operations is an image that has mostly consistent values and can be converted to black and white via a simple threshold.
Edit: It's nice to see a little competition. nikie has proposed a very similar approach, using subtraction instead of scaling to remove the variations in the white level. My method increases the contrast in the regions with poor lighting, and nikie's method does not - which method you prefer will depend on whether there is information in the poorly lighted areas which you wish to retain.
My attempt to recreate this approach resulted in this:
for y in range(height):
for x in range(width):
greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0], 255 + impix[x,y][1] - whitepix[x,y][1], 255 + impix[x,y][2] - whitepix[x,y][2]))
I'm working on a combination of techniques to deliver an even better result, but it's not quite ready yet.
One common way to remove the different background illumination is to calculate a "white image" from the image, by opening the image.
In this sample Octave code, I've used the blue channel of the image, because the lines in the background are least prominent in this channel (EDITED: using a circular structuring element produces less visual artifacts than a simple box):
src = imread('lines.png');
blue = src(:,:,3);
mask = fspecial("disk",10);
opened = imerode(imdilate(blue,mask),mask);
Result:
Then subtract this from the source image:
background_subtracted = opened-blue;
(contrast enhanced version)
Finally, I'd just binarize the image with a fixed threshold:
binary = background_subtracted < 35;
How about detecting edges? That should pick up the line drawings.
Here's the result of Sobel edge detection on your image:
If you then threshold the image (using either an empirically determined threshold or the Ohtsu method), you can clean up the image using morphological operations (e.g. dilation and erosion). That will help you get rid of broken/double lines.
As Lambert pointed out, you can pre-process the image using the blue channel to get rid of the grid lines if you don't want them in your result.
You will also get better results if you light the page evenly before you image it (or just use a scanner) cause then you don't have to worry about global vs. local thresholding as much.

Resources