我正致力于将艺术效果应用于图像。 你能告诉我如何达到这个效果吗?
任何意见都值得赞赏.....
输入图片: http://www.flickr.com/photos/vineet_aggarwal/4205359333/
输出图片: http://www.flickr.com/photos/vineet_aggarwal/4205359335/,
答案 0 :(得分:1)
请参阅: http://www.codeproject.com/KB/graphics/CBitmapEx.aspx?msg=3312512#xx3312512xx
PS:您必须首先了解作者编写的CBitmapEx类。
答案 1 :(得分:0)
第二张图片中的考拉是3D图像...计算机无法轻易地从第一张图像中找出应该抬起哪些位以及应该降低哪些位。
我建议>人类<做这项工作,虽然电脑可以帮助......
如果您有所有图块的高度列表,(由图形艺术家创建......也许你自己?),您可以一次将它们渲染为一个空白帧缓冲区。从最后面的瓷砖到最前面的瓷砖依次使用抗锯齿渲染它们。看起来为每个图块选择的颜色值基于相应的方形矩形中的平均颜色值(可以或可以不落在精确的像素边界上)。但是如何计算平均值对我来说并不清楚,它可能基于RGB或HSV,它可能是一个简单的均值或加权均值,非线性或其他什么,你可能需要考虑伽玛校正(见链接)。 / p>
据推测,画布(在渲染之前)到画布的颜色空间会变形,以匹配原始图像中相应区域的颜色。
我忽略了我想象你可能不关心或想要花时间的细微之处,比如阴影和高光是否应该在更暗或更亮的瓷砖上比在颜色变形后的某些参考瓷砖更暗或更亮,以及场景中的反射。 OTOH如果这些细节很重要,你应该考虑使用OpenGL在3D中构建整个东西。 OTOOH(三只手 - 哇)也许你根本不应该使用VC ++并使用绘图包来做...
这是一个代码大纲图,我没有完全考虑过,这只是一个粗略的草图,你需要掌握这个,解决我可能已经做出的任何问题和错误,并使它成为你自己的: -
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);
JPEG库不一定会为您提供RGB数据,可能是HSV或其他内容,我现在忘了。但是你需要的色彩空间转换主要是数学问题,需要一点点捏造和四舍五入以及其他必要条件。
我还没有提到过很多舍入,缩放和定位问题。
主像素缓冲区的每个像素为3个字节,而瓦片为4个字节(RGBA)。
阅读:
http://en.wikipedia.org/wiki/Anti-aliasing
和
http://en.wikipedia.org/wiki/Alpha_compositing
和
http://en.wikipedia.org/wiki/Color_space
和
http://en.wikipedia.org/wiki/Libjpeg
和
http://en.wikipedia.org/wiki/Libpng
和
http://en.wikipedia.org/wiki/Zlib(因为libpng使用zlib)
和
http://en.wikipedia.org/wiki/Gamma_correction
恕我直言使用C ++很好,但是你会工作得如此低级而且不使用多态,所以OO概念和封装可能不会比C概念和封装更有益。随意将方法编写为C ++命名空间中的函数和/或C ++对象上的方法,并将像素缓冲区包含为成员变量(或其他),如果您希望使代码与其他C ++的形式更加一致。就个人而言,我会尝试用纯C编写它以获得最大的可重用性。您可以通过在标题中使用预处理器指令有条件地使用extern“C”来使大多数C模块与C ++一起使用。
修改
my_jpeg_read_func,my_png_read_func,grabcolorvalue,create_colored_tile_by_color_space_warping,draw_tile,my_jpeg_wrapper_write和report_error_to_user以及其他一些必须自己编写,您可能需要在项目中包含libjpg,zlib和libpng并添加标题和/或#includes
修改
虽然这可以在OpenGL中完成,但我建议渲染瓷砖顶部的圆角突出显示形状可能有点难以做到令人信服地 。任何OpenGLers或Direct3D程序员都得到了答案?
修改
将ref-tile.jpg更改为ref-tile.png。