【问题标题】:Applying effects on image using VC++?使用 VC++ 对图像应用效果?
【发布时间】:2010-12-29 02:23:21
【问题描述】:

我正在努力将艺术效果应用于图像。 你能告诉我如何达到这个效果吗?

感谢任何输入.....

输入图像: http://www.flickr.com/photos/vineet_aggarwal/4205359333/

输出图像: http://www.flickr.com/photos/vineet_aggarwal/4205359335/,

【问题讨论】:

    标签: image image-processing visual-c++


    【解决方案1】:

    第二张图片中的考拉是 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。

    【讨论】:

      【解决方案2】:

      请看: http://www.codeproject.com/KB/graphics/CBitmapEx.aspx?msg=3312512#xx3312512xx

      PS:你要先了解作者写的CBitmapEx类。

      【讨论】:

      • 嘿,在不使图像变灰的情况下压印图像的方法是校正整体色调和亮度以匹配预压印瓷砖(即单一平面颜色),在给定的范围内这是可能的瓷砖颜色。可能还需要混合一些纯色以获得更接近的颜色匹配,但这可能是一种折衷方案。显然,接近色谱边缘的颜色存在基本限制——你不能在不将其变灰的情况下突出显示白色瓷砖,也不能在不将其变灰的情况下对黑色瓷砖进行阴影处理。这取决于您希望图像的外观。
      • 如果是我,我会在白色、接近白色、黑色和接近黑色的瓷砖上做出妥协,而不是其他,并建议用户使用不要太接近的颜色变成黑色或白色。
      • 另一种选择是朝着一些漫画家的方向前进 - 保留一点缓冲区,其中像素应该真正比白色更白或比黑色更黑,但不能因为颜色空间限制,并在最终图像中,围绕这些区域的飞溅画一条细线。如果您不输出到计算机显示器,另一种选择是以其他方式增加某些区域的表观亮度,例如使用专业照明。在计算机显示器上的计算机成像范围内,在没有漫画家妥协的情况下,您的选择受到严重限制! “坏考拉——太白了”?
      猜你喜欢
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多