第二张图片中的考拉是 3D 图像...计算机无法从您的第一张图片中轻松计算出应该提高哪些位,应该降低哪些位。
我建议>人类
如果您有一个所有图块高度的列表,(由图形艺术家创建......也许是您自己?)您可以一次将它们渲染到一个空白帧缓冲区中。从最后面到最前面的瓷砖按顺序使用抗锯齿渲染它们。似乎为每个图块选择的颜色值是基于相应方形矩形中的平均颜色值(可能会或可能不会落在确切的像素边界上)。但是我不清楚平均值是如何计算的,它可能基于 RGB 或 HSV,它可能是一个简单的平均值或加权平均值、非线性或其他什么,您可能需要考虑伽马校正(请参阅链接)。
据推测,画布上的图块(在渲染之前)的颜色空间发生了扭曲,以匹配原始图像中相应区域的颜色。
我忽略了一些细微之处,我想您可能不关心或想要腾出时间来处理阴影和高光是否应该在颜色扭曲后比某些参考图块更暗或更亮的校正,以及场景中的倒影。 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 中完成,但我建议渲染图块顶部的圆形突出显示形状可能有点难以做到令人信服 .任何 OpenGL 或 Direct3D 程序员得到答案了吗?
编辑
将 ref-tile.jpg 更改为 ref-tile.png。