views:

902

answers:

10
A: 

You'll have to handle shades of off-white as well. Probably when they made the iamges initially and set the background color, there was some anti-aliasing, and then when saving as a jpg, not all colors will be preserved perfectly. So if you are making a particular color transparent, it's not going to get all the shades of that color which will leave many artifacts. You need something that will do transparency proportional to how close a color is to your key color. This might be something easier to do as a batch script in something like Photoshop, but I don't know if this is something you are needing to do in real time.

AaronLS
well.. that could change you know.. from time to time.. it would be nice to have something dynamic.. to handle all the images for future members..
Arcturus
After looking at the picture, if your source can provide them in a non-lossy format, like bitmap, you probably won't have the problems you are having. It looks like the off-white is from the compression that occurs with jpg. Maybe they can host both jpg's and bmp's on their server, using the jpg's on their site, and leaving the bmp's in the same location. So when you pull the images you can replace the extension, pull the bmp, and replace the color.
AaronLS
Yeah I could try that, but I don't think they have the original source, because its a collection of pictures submitted by many who make those frames.. thanks for the suggestion though..
Arcturus
A: 

There's no (remotely easy) way to deal with this problem programatically. The white artifact-y areas around the edge of the image are the result of pixels that are nearly white but not quite, so they don't pick up the transparency effect. There are also a couple of spots on the mask/coffee mug that are pure white, so they become transparent and thus grey.

Your best bet is to contact the original site's webmaster and see if they can send you the original images, hopefully in photoshop or some other format where the original layers are preserved separately. You could then re-generate the images in a format that preserves the original transparency (PNG or something like that) or else uses your gradient for the background (it would very tough to get this right, since you don't know exactly where within the gradient the picture will be rendered).

I'd go with some sort of border around the images, as you suggested.

MusiGenesis
Hmm yeah.. there are always new members coming along, and I want to be done with it once and for all really... Thanks for your time though.. its much appreciated.. perhaps I will use the border solution after all..
Arcturus
+1  A: 

Loop through each pixel in the image, if R,G and B is higher than, say, 230 then replace the color with your desired color(or transparent). Maybe even weight the new color depending on how far from 'true' white the old color is.

Expect to get problems if the actual image is white also, otherwhise you will end up with a grey stormtrooper :)

This could be changed to a more general purpose solution that wouldn't grey out the storm trooper by doing a psuedo graph traversal. Start at the top left white pixel, then go left/down/up/right to each pixel matching the 'close enough' criteria. Basically a flood fill. This might still cause trouble if there is blending on the edges of the actual image (a blend of white and brown that looks plain wrong on gray).
CoderTao
I like your answer.. its clean and simple.. When I was eating diner with my gf this afternoon it struck me too.. Your solution with an added, "no changes here" zone/block for the stormtrooper :)
Arcturus
Ok I tried your solution as well.. it still looks like crap with white borders at the edges.. damn this white is ugly ;).. Thanks for your time though!
Arcturus
+1  A: 

You will not be able to do this automatically with anything like 100% accuracy.

The reason for this is that the only info you have is the colour which you know that some pixels in the image are attempting to blend nicely with. Only some pixels in the image will actually be using colours at or close to this value for the purposes of shading into the background, others will be using (in the case white) because the actual object represented are in fact white (damn the precision of these imperial storm troopers).

The sort of sophisticated machine learning to detect which is which is an interesting problem domain, and might be a fun project for you but it certainly won't make for a quick solution to your immediate problem.

The other problem you have is that, even if you could detect with good reliability those areas of the image which are attempting to blend into the back ground you will have issues 'unblending' them and then reblending them into your new background colour unless the colours are reasonably compatible. In this case your gray may work since it is a broad spectrum colour like the white.

The technique you want to use is as follows:

  • Use a flood fill algorithm to select, from the edges of the image inwards all pixels within x%(1) of the known backdrop colour.
  • For those pixels set their alpha channel to a value as a proportion of their match to the original colour and eliminate the colour cast which was associated with it.
    • So if the backdrop is RGB value a,b,c and the pixel is a+5,b,c-7 then the result is RGBA 5,0,0,((a+b+c-7)/(a+b+c)*256)(1)
  • composite this alpha blending image over a pain square of the new back ground colur.
  • render the result with no alpha channel as the new image.

This will still have issues for objects whose colour is close to the either background colour. * in the case of the original then it may be that shadowing is being used to imply the presences of the object, as such the flood fill will 'invade' the inside of the image. * in the case of the latter the resulting image will lose definition of the object and no subtle shading, highlights or just plain lines will be present to indicate where the object ends and the back ground ends.

This is a very rough first approximation but may cover a reasonable percentage of your target. Those pictures with transparent fully enclosed holes (like the gaps in the outer arch in your example) are not likely to ever work nicely in an automatic fashion since the algorithm will be unable to distinguish between white holes and white stormtrooper.
You may wish to make you algorithm highlight the regions of the picture it plans on reblending and allow the simple selection of regions to include/exclude (using the magic wand selection tool from Pain.Net as an example of how to do this if you want to be fancy, allowing simple per pixel selection for less upfront effort.


  1. the value for x will be something you tune - it may be that, based on some aspects of the image (say the proportion of the image which is close to the back ground colour) you can tweak it automatically.
  2. Note that this formulae assumes a close to white colour, for close to black you would want to invert
ShuggyCoUk
+3  A: 
CoderTao
While its not perfect, your answer has the most upvotes, so I have accepted your answer; I have given up my quest for this image decoding. I placed a border around the white image, like a painting.. Thanks for the help!! :)See http://www.501st.nl/Members.aspx ;)
Arcturus
A: 
Arcturus
A: 
Arcturus
Slightly different question, is the odd... border thing constant? (IE do most/all images have that same border, with a user supplied image in the interior?)
CoderTao
No, there are different kind of borders... i.e.: compare the bikerscout image (above) with the stormtrooper border: http://images.501stforums.com/memberdata/54/04/tk5404_full.jpg
Arcturus
Well, the line of thought (less useful as it is now), is that you clean up the border by hand, (which it looked like you were doing with the green method), then mark an interior portion as 'area to merge' (green, magenta, fluorescent pink, whatever works for you), then merge the central area against the original. You have the hand cleaned border and the by definition cleaned central area. Only works if you know the border though.
CoderTao
The center of the overlay image was transparent, and it merged beautifully with the original image though.. but aparantly my overlay was not perfect..
Arcturus
A: 
CoderTao
Yeah I tried this with my second approach, but when I make the green transparent, it goes wrong again ;).. (see the green borders).. The problem is the background of my own site I guess.. We use a gradient in the background, and without having to precisely place the pictures, transparent background is the way to go.. Ah well.. We do have another idea. We let the user upload their own action picture, add a nice stormtrooper picture frame, and let that be the profile pic.Has nothing to do with this problem, so avoiding it will also solve it I guess.. thanks for helping though.. much appreciated
Arcturus
I think that you could modify the mask image such that the green border is transparent (when doing hand touch-up); then just use the red colored area to merge against the original image; result being a transparent area on the border, and merged area at center. Though, either way, it's been fun.
CoderTao
A: 

i wanna ask a question please if i am dealing with words as images i wanna fill gaps in letters

what algorithm do u advice me to use?

lobna
None.. its quite hard on JPEGs
Arcturus
A: 

The images i am working on is Gray scale images not colored

lobna