Applying effects on image using VC++?
I am working on applying artistic effects to image . Can you please tell me how to achieve this effect ?
Any inputs are appreciated .....
Inp开发者_运维技巧ut Image :
http://www.flickr.com/photos/vineet_aggarwal/4205359333/Output Image:
http://www.flickr.com/photos/vineet_aggarwal/4205359335/,Please See: http://www.codeproject.com/KB/graphics/CBitmapEx.aspx?msg=3312512#xx3312512xx
PS: You have to First understand the CBitmapEx class written by the Author.
The koala in the second image is a 3D image... the computer cannot easily work out from your first image which bits should be raised and which bits should be lowered.
I suggest a >Human Being< to do the job, though a computer could help...
If you have a list of the heights of all the tiles, (created by a graphics artist... yourself perhaps?) you can render them into a blank frame buffer one at a time. Render them using anti-aliasing in sequence from ther backmost tiles to the front-most. It appears that the colour value selected for each tile is based on the average colour values in a corresponding squarish rectangle (that may or may not fall on exact pixel boundaries). But how the average is calculated is not clear to me, it may be based on RGB or HSV it may be a simple mean or a weighted mean, non-linear or whatever and you may need to consider gamma correction (see links).
Presumably the tile (before being rendered) to the canvas has its color space warped to match the colour of the corresponding area in the original image.
I am ignoring subtleties I imagine you probably don't care about or want to make time for like whether the shadows and highlights should be corrected to be darker or lighter on darker or lighter tiles than some reference tile after colour warping, and reflection in the scene. OTOH If these fine details are important, you should consider building up the whole thing in 3D using OpenGL. OTOOH (three hands - whoopee) maybe you should not use VC++ at all and do this using a drawing package...
Here's a code outline illustration, I haven't thought it through entirely, this is just a rough sketch, you'll need to get to grips with this, fix any problems and mistakes I may have made and make it your own:-
int input_width, input_height, tile_width, tile_height;
int heights_width, heights_height, err=0, height, x, y;
char* input_pixels=NULL, *output_pixels=NULL, *tile_pixels=NULL;
char* modified_tile=NULL; int *heights_data=NULL;
if (!err) err =my_jpeg_read_func("koala.jpg",&width,&height,&input_pixels);
if (!err) err =my_png_read_func("ref-tile.png",&width,&height,&tile_pixels);
if (!err) err =my_read_tile_heights_func("tile-heights.csv",
&heights_width,&heights_height,&heights_data);
if (!err) err =(output_pixels = malloc(input_width*input_height*3))==NULL;
if (!err) err =(modified_tile = malloc(tile_width*tile_height*4))==NULL;
if (!err) for (height=0; height<256; height++) for (x=0; x < heights_width; x++)
for (y=0; y<heights_height; y++) if (heights_data[y*heights_width+x]==height) {
int colorvalue = grabcolorvalue(input_pixels, input_widthh, input_height,
heights_width, heights_height, x, y);
create_colored_tile_by_color_space_warping(tile_pixels, modified_tile,
tile_height, tile_width, colorvaLue);
draw_tile(output_pixels, input_width, input_height, x, y, heights_width,
heights_height, modified_tile, tile_width, tile_height);
}
if (!err) err=my_jpeg_wrapper_write("koala-out.jpg", output_pixels,
input_width, input_height);
if (input_pixels) free(input_pixels); input_pixels=NULL;
if (output_pixels) free(output_pixels); output_pixels=NULL;
if (tile_pixels) free(tile_pixels); tile_pixels=NULL;
if (modified_tile) free(modified_tile); modifie_tile=NULL;
if (err) report_error_to_user(err);
The JPEG library will not necessarily give you data in RGB, it might be in HSV or something else, I forget now. But the color space transformations you need are a matter largely of maths with a little bit of fudging and rounding and other kludges where required.
There's lots of rounding and scaling and positioning issues too that I haven't mentioned.
In the above 3 bytes per pixel for main pixel buffers but 4 bytes (RGBA) for tiles.
Read about:
http://en.wikipedia.org/wiki/Anti-aliasing
AND
http://en.wikipedia.org/wiki/Alpha_compositing
AND
http://en.wikipedia.org/wiki/Color_space
AND
http://en.wikipedia.org/wiki/Libjpeg
AND
http://en.wikipedia.org/wiki/Libpng
AND
http://en.wikipedia.org/wiki/Zlib (since libpng uses zlib)
AND
http://en.wikipedia.org/wiki/Gamma_correction
IMHO Using C++ is fine, but you'll be working so low-level and not using polymorphism so probably OO concepts and encapsulation is not going to benefit you that much over C concepts and encapsulation. Feel free to write the methods as functions in a C++ namespace and/or methods on a C++ object and include the pixel buffers as member variables (or whatever) if you want to make the code more consistent in form with some other C++ you have though. Personally I would try to write it in pure C for maximum reusability. You can make most C modules work with C++ by using extern "C" conditionally with preprocessor directives in the headers.
EDIT
The my_jpeg_read_func, my_png_read_func, grabcolorvalue, create_colored_tile_by_color_space_warping, draw_tile, my_jpeg_wrapper_write, and report_error_to_user and maybe some others have to be written yourself, and you may need to include libjpg, zlib and libpng in your project and add headers and/or #includes.
EDIT
Though this could be done in OpenGL, I would suggest that rendering the rounded highlighted shapes of the tops of the tiles well might be a teensy bit hard to do convincingly. Any OpenGLers or Direct3D programmers got an answer?
EDIT
Changed ref-tile.jpg to ref-tile.png.
精彩评论