How to mimic Dabble Color Schemes? - php

How would you develop something similar to what is described in this DabbleDB blog post?

Just answered a kinda related SO question yesterday. Some of the concepts there, along with the resulting test code (on git hub) could be a good start.
As evolve mentions, scanning every pixel in an image (or even just the border) can be resource intensive. However, in this case (since you want to identify far more than just average color) it may be the way to go. Resizing the logo to a sane size would help reduce the server load, and shouldn't really effect the output.
Update: For these examples assume an image object has been created and $width and $height have been determined using imagesx(), getimagesize(), etc.
Background Color
The first thing we needed to do was figure out the logo’s background color. And that’s all the first version did, by using the corner pixels.
Here use imagecolorat() to find the corner colors. Alternatively, use the average border color method from the referenced answer at the top.
$color = imagecolorat($image, 0, 0); //do this for each corner
$rgb = imagecolorsforindex($image, $color); //convert each color to a RGB array
//average colors
Saturation
It turns out color theory has a way of measuring interestingness: saturation. So we pulled out an interesting color from the logo. Using the same color for the border and the text made things a bit more monotone than we wanted, so finally we decided to try and grab two interesting colors if they’re present.
You can use the RGB to HSL functions at the imagecolorsforindex() manual page along with the pixel scanning code mentioned at the top to find color values with high saturation.
Luminance
We turned again to color theory and realized we could use the border color’s luminance to decide whether black or white text was more suitable.
This SO thread lists different RGB to luminance calculations. I'm not certain what method is best (or technically correct) to convert 0-255 RGB images. But for what this is accomplishing (should the text be dark or light), I don't think it'll matter that much.

Related

Image segmentation and Image Recognition - How to recognise the coordinates of a white patch in a black background image?

Aim: Find the white patch with the biggest area. And if possible then confirm if it is a circle. Then find the average centre of this patch and radius.
I have thought of creating an edge around the images, but I don't know how that would help in finding out the area of the patches.
I am trying to accomplish this and if anyone can guide me in the right direction, I would really appreciate it.
I am currently using php.gd library and that is the only tool I have.
Thanks
Detecting edges in images is actually quite simple. The most standard way is to use an image convolution operation and choosing the right kernel to sweep over your image. There is a function in php.gd called imageconvolution where you can specify an input image, a convolution kernel, a divisor and an offset. The divisor simply divides all values in the kernel by this value and the offset adds a value to each value in the kernel. As such, assuming that your image is loaded into the array $im, you would do this:
$edgeMatrix = array(-1,-1,-1,-1,8,-1,-1,-1,-1);
$divisor = 0;
$offset = 0;
imageconvolution($im, $edgeMatrix, $divisor, $offset);
Note that imageconvolution mutates the original input image, so $im will contain the edge detected result. Make sure that you have a copy of the original image somewhere in case you need it.
$edgeMatrix = array(-1,-1,-1,-1,8,-1,-1,-1,-1); is the standard Laplacian convolution matrix and is used quite often for edge detection tasks.
However, there is a function called imagefilter where there is an edge detect flag - IMG_FILTER_EDGEDETECT. This function filters an image given one of several options, and edge detection is one of these options. As such, you would do this:
imagefilter($im, IMG_FILTER_EDGEDETECT);
As with imageconvolution, imagefilter also mutates the input image, so again make sure that you keep the original image somewhere if you need it.
Hopefully one of these will work for you!

Convert white parts in image to transparent to simulate printing

I am currently developing an AJAX application using PHP and Javascript that allows people to upload images that will be printed on foil. Since I will be using a standard CMYK printer, it won't print any white parts, but rather just leave those spots blank - a thing that usually does not make a difference on white paper, but here it does, since I'm printing on foil. It gets more complicated when you consider that a grey dot will become semi-transparent black, and I'm not even talking of colors yet.
Yet I would like to create a PNG file with an alpha channel that will simulate the printing process, so I can give a preview of how the printed foil would look when being hold against different backgrounds.
Now I do understand the basic theory of subtractive and additive color models and also of RGBA and CMYK, but then again it's only the basics and here I'm kind of at a loss of how to proceed. I guess in theory you would convert every pixel into CMYK and interpret each channel as a scale from transparent to color instead of from white to color, but how would you translate that back into RGBA?
The nicest thing would, of course, be if ImageMagick would provide such a feature .... does it, or do I have to loop through the pixels manually? If the latter, how would I do the calculations?
I don't know if this has been an issue before. I couldn't find anything on either Stackoverflow or Google, but maybe I just missed the right keywords. Any further reading, food for thoughts or hyperlinks with a note "we discussed this a million times, idiot!" would be warmly welcome.
Thanks
What you basically want is to add an alpha channel to the uploaded image and create a PNG file.
The alpha channel should represent the opacity of the printed color. To generate it, you have several options:
Take a copy of the image, convert it to grayscale, invert it and use it as alpha channel.
Create an alpha channel compute the alpha value of each pixel derived from the original image as: alpha = 1.0 - min(red, green, blue) (use 255 instead of 1.0 depending on whether you're using integer or floating point numbers).
Convert the original image to CMYK (using a color profile and not the poor formulas youn find all over the internet) and use it as the basis to create the alpha channel for the original RGB image: alpha = max(cyan, magenta, yellow, black).
Come up with an even better formula to compute the transparency of each pixel such as: alpha = min(0.2 * cyan + 0.5 * magenta + 0.1 * yellow + 0.7 * black, 1.0)
The last one is just a guess of the relative opacity of each color. You can certainly improve it.

PHP, detecting watermarked images?

I have a library of like 1 million images, and roughly half of these are watermarked with the same, half transparent watermark in the same spot.
Where do I begin, detecting the images with the watermarks? Is there some standard tools for this purpose?
If according to your question, you just want to detect the images that are watermarked, you can use the following algorithm:
Extract a sample of the watermarking image Scan the watermark image
pixel by pixel and store the first pixels in an array. Scan each
image pixel by pixel and store in an array. Whenever a row matrix
from the image being scanned contains elements of the array in the
same order, it's most likely a match.
The code could be something like this:
$no_of_pixels = what_you_got;
$matched = 0;
$thumbpixels = array();
$wmark = imagecreatefrompng("watermark.png");
list($width, $height) = getimagesize("watermark.png");
$tesimage = imagecreatefrompng("test.png");
for($h = 0; $h < $height; $h++){
for($w = 0; $w < $width; $w++){
if(imagecolorsforindex($testimage, imagecolorat($testimage, $w, $h)) == $thumbpixels[0]){
while($thumbpixels[$i++] === imagecolorsforindex($tesimage, imagecolorat($wmark, $w, $h)) && $no_of_pixels != $matched){
$matched++;
}
if($matched == $no_of_pixels) echo "Voila, we found it!";
}
}
}
EDIT
Just seeing your thumbnail example. If you just want to detect text, you can try tesseract-ocr or PhpOCR.
You may also consider PHPSane
Detecting almost any feature in an image is called Object Detection. There is a widely used libray called OpenCV. It has a very simple SDK, although setting up can be a real pain. It is well supported for C/C++ and (nearly well supported for) Python. It took me arnd 3 weeks to train my own Classfier (training), first time I started using OpenCV.
But I would not really depend on this solution entirely and consider my priorities. Also, it is very hard to achieve good rate with custom classifier. Other methods are more time consuming.
In short, not with complete accuracy.
At best, you could only apply heuristics on the image to see if it matches an exact watermark, and get a confidence rating -- for example, if the watermark if a 50% white overlay, then a scene that was predominantly white could give a false positive, and of course the inverse is true.
There are also problems that could arise if the images use a lossy compression, such as JPEG, as the edges, and the saturation may result in a watermark that isn't as saturated as expected, or as exactly positioned as expected.
Because you know where the watermark always is it is possible that you could use imagecolorat and imagecolorsforindex to get the alpha value for pixels both inside and outside of the watermark. I would expect the alpha values to be similar when there is no watermark, and different when there is (within some threshold that you would need to determine). Of course, this may not work on all images so if you need 100% accuracy you would probably need something more reliable.
In your case, where you are looking for the same logo in a predictable location, it is relatively simple. However it's much, much simpler and faster (as per my comment elsewhere) to match a copyright notice in the meta data!
A watermark is not going to produce fixed changes to the content - each modified pixel will obtain a new value based on the watermark and the image itself. Hence you need to extract this information - I'd go with diferentiating the image and just looking at the magnitude of the derivative (not the phase).
Then it's simply a matter of correlating the differential with one of just the watermark (or lots with the watermark and other content).
You really don't want to be doing this kind of image processing in PHP unless you're happy writing your own extensions. Most image processing toolkits will support differentiation and correlation.
BTW: if you don't know how to differentiate an image, and/or can't understand how to correlate an image, please don't ask - this is not the right forum for that discussion
Well if there is no tool to do this, you could try the following:
identify where the watermark appears as a percentage of pixels, eg bottom right 40px x 100px
For each image, make a temp copy and crop out the location of where the watermark would appear. This should leave both the watermarked version and the non watermarked version as the same
compare the images - e.g. combination of width x height, filesize, CRC or actual pixel comparison, though for a million images you'd need some serious CPU power.

How do I re-create Actionscript's ColorTransform with php gd image library to colorize an image?

I'm using a template of sorts, as you can see here: http://i.imgur.com/TtOHa.png
In the game itself, you can choose any color to apply to that, and using actionscript's ColorTransform for red (255, 0, 0) you will get this: http://i.imgur.com/40FoO.png
After searching and testing for a few days, I'm just getting nowhere with this. Using imagefilter with IMG_FILTER_COLORIZE just isn't cutting it. It just ends up tinting it basically, and it needs to fully change the color and keep intact all the different shades from the template.
I thought the best solution would be to loop through each pixel and convert to HSV for the template and use the V value with the new color but it won't work well if you use a darker color to colorize the object with. I tried to come up with a formula on just how bright/dark the color should be according to the template but I just can't come up with anything.

Automatically choose a good border color based on background color

I'm looking for any resources on choosing "good" colors based on one specified color. Specifically if I gave an input of say... #6e93a8, a nice corporate blue, it could spit out a darker blue for a border color and perhaps a white or black for text based on how dark the given color is. Keep in mind I can input any hex value.
I have a feel this is just messing around with adding and subtracting hex values, but I'm hoping someone has done this before and has found some good resources or an algorithm.
Thanks!
Matt Mueller
If you already know what you want to do to the colors and you just need an algorithm for transforming the colors then check this answer which contains the algorithm for converting between RGB and HSV (and back). From then on you can alter the HSV values (to make the colors ligher, darker etc) or apply rules if the color is dark or light.
Are you looking for an algorithm or just a tool? Kuler is a web-based tool for designing color schemes that I think would serve your purposes

Categories