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.
Related
Ok, so I am taking full color PDFs and trying to convert them to black and white images to then make them black and white PDF's.
Currently I am attempting to do this with imagemagick and i am for the most part successful with breaking them PDF into separate images. However once creating the separate images I want to make full size black and white copies next to the color copies as well as thumbnails thereof of both. Which that part I feel I'll be able to figure out on my own.
What I am having trouble figuring out is how to get them to become black and white. Not necessarily grayscale, since grayscale will still use colored ink in most printers to come up with the varying shades of gray. From which I am trying to avoid.
Is there a means I can do this with imagemagick or is my thought process all wrong?
Also worth noting is I am trying to do this through a browser and server side process with PHP
I think you are looking for "Two Colour Quamtisation" as described in Anthony Thyssen's excellent work here.
Basically, you use quantisation to pick the best two colours to represent your image, then force the darker one to black and the lighter one to white. So your processing becomes:
convert image.png -colors 2 -colorspace gray -normalize result.png
Btw, I presume you found and are using pdfimages (part of the poppler package) to extract the images in original quality.
Overview:
I am working on a video creation project. The technology I am using are: imageMagick, php, ffmpeg.
Current Status:
Currently the project is able to create videos using images and texts and few basic transitions. The way I am doing it is using imagemagick to create gif using input images(with transition effects in them) and then converting all gifs to videos and atlast concatenating the video together.
Next Move (My question):
I am now set to take it to the next level. So, what I am having is a video(1920x1080) with some white frames(1280x720) that keeps shifting in each frame. I want to replace those white frames appearing in some frames of the video with some images(1280x720) that I wish to use. Please see the image here and you will get an idea: These are just two frames from my video. If you can see carefully the images are shifting(white space is not constant).
Expectation:
So, I want to fill those white space with one of my own image. If the case would have been for only one frame I could have used ffmpeg to overlay image on the exact width and height. But here the white space is not fixed and keeps shifting in all the frames and there are a lot of frames. So, I am looking for something like opencv or some other technology that can be used for object detection in a video or in a set of frames and replace the detected area with some other image.
I just need a kick. So, if anyone has already worked on something like this just suggest me what technology can I use. Thanks in advance.
It all depends on exactly what you can assume :
If you can safely assume that your rectangle's boundary is never occluded (hidden) somehow, you can try finding the edges in your image (like OpenCV's Canny edge) and then look for rectangular shape (corners forming a warped rectangle, or the very popular Hough Lines).
If the rectangle you're looking for is always white, you can threshold the image in a colorspace like HSV to look for maximum value (the V in HSV ~ brightness) then rectangular shape search in a binary image.
If your corners are occluded sometimes you'll have to do some tweaking with your image, like morphological operations ("grow and contract" binary thresholded image), then Hough Lines could do the trick.
Note that this answer assumes that once you know where the rectangle is, "you're done", and you just have to overwrite the rectangle with custom content.
I also do not check for any time-continuity : you video frame might jump around based on the frame-by-frame appearance of rectangle. You'd have to include some knowledge about previous positions.
I have a task to write a PHP script that makes objects in the center of their pictures, For example
Some of the pictures are horizontally oriented and some are vertically oriented based on that and the size of the white space I have to Crop/Add white space to the original picture.
The first method I had is by detecting the borders of the object within the picture but some picture doesn't have clear white background e.g:
This Picture has extra white space on the borders and has gray gradient as the background which makes it harder to detect the object's borders, So I tried to apply The Sobel operator by Imagemagick
exec("convert 1.jpg -define convolve:scale='50%!' -bias 50% -morphology Convolve Sobel -solarize 50% -level 50,0% ssc1.jpg");
The result was ok
And Now I have to find the borders in the filtered image, And the question is
What's the best way to find the coordinates of the borders (the output should be X1,X2,Y1,Y2)?
I have read some similar problems like this one that converts the image to text and remove white (black in my case) pixels but I'm not sure what's the best approach to solve this (I'm newbie in Image Processing).
I don't have time today to do this in ImageMagick, but I did an experiment in Photoshop and it seems to work nicely - at least for your lady on a gradated background.
I took the image and duplicated its layer in Photoshop (Cmd+J).
I set the Blending Mode of the upper layer to Hard Mix
I did Image->Trim from the menu at top of screen.
There is a good explanation of how Hard Mix works here at the bottom of the page.
You could emulate the Hard Mix effect using ImageMagick's fx operator like this here
Hope the approach helps.
I want to crop a rectangular image to a non-rectangular shape. I realize that if you take that completely literally, it's not possible. What I want to end up with is image X, cropped to shape Y, on a transparent background.
Let's say for example that I want to take a picture of the Idaho flag and crop it to the shape of the state of Idaho. I imagine I would do something like this:
Create an image that has opaque pixels for the shape of Idaho, transparent pixels everywhere else
Read and store some kind of bitmap for this Idaho state image
For each opaque pixel location in the Idaho state image, copy the corresponding pixel from the Idaho state flag image and place it on a blank, transparent canvas
Step 1 would obviously be done manually, but the rest would be done programatically. I think I have the right idea in general but I don't know how I'd approach the specifics. Can anyone point me in the right direction?
As far as implementation technology goes, I'm a PHP guy, so using gdLibrary or something that works with PHP would probably be the best way for me to go.
I would think it would be much easier to do by simply adding a bitmask or alpha channel. In that case you would use a negative mask image of your shape and then simply apply it to he regular image as a mask and then save out in a transparent format. Ive never actually done this with GD or ImageMagick but i would think its available as Jerry suggests.
Acutally here is a blog post form a similar SO question that might help: http://about.phalacee.com/geek/creating-mask-layers-using-php-gd
The usual way to do something like this would be to use white (all 1's) and black (all 0's) for your outline instead of transparent and opaque. Then you AND that image with the image you're trying to crop. The result is 0's where the outline image had 0's, and the other image where the outline had 1's.
You may also need to invert your outline image, and AND the inverted version with the background image. Then you OR the background image with the foreground image to produce a composite of the foreground image in the shape of Idaho (to use your example) and the background image everywhere else.
Depending on the capabilities of the library you're using, there's a good chance that kind of capability is directly available though. Just for example, Windows has this capability in the MaskBlt function.
In php using ImageMagick is probably your best bet:
$source = IMagick("sourcefile");
$mask = IMagick("maskfile");
$mask->adaptiveResizeImage($source->getImageWidth(), $source->getImageHeight(), true);
$source->compositeImage($mask, imagick::COMPOSITE_MULTIPLY, 0, 0);
$source->writeImage("newfile");
$source->clear();
$source->destroy();
sourcefile must be the source image as you like, maskfile must be a mask file that has the alpha channel set correctly for the shape you want.
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.