[-blogs-]Cimg代码初探

Cimg代码初探

程序设计最为激动人心的地方,在于丰富的并且容易被查阅到资料。比如对于图像处理,固然有Opencv等较为丰富、被广泛知晓的类库;也有其他很多具有一定特色的类库。在这段时间里面,我对CImg图像处理库进行了初步研究,并且做小结如下:

一、类库总体情况

总体感觉,CImg是一个“小家碧玉”类型的类库。这里的“小”,不仅体现在代码结构上、体现在代码数量上,我觉得很大程度上也体现在代码内容上:比如代码的缩进都是采用最节省空间的方法,大量采用了连续处理的方法,其实现的功能也是比较有“趣味”,但不是解决实际问题的方法

再比如,已经将许多图片程序以“硬编码”的方式编入了类库,这些都体现了程序设置者的“偏执”,或者叫做“个性”,但是并不能将CImg变成一个更有用的类库。

但是反过来说,CImg实现的许多效果,的确是匠心独运,简直可以说是"so COOL"

炫动的菜单背景

非常适合做帮助的flag

光怪陆离的效果

游戏

3D效果

鱼眼

可视化的Gamma矫正

足球轨迹。

二、研究思路和计划

1)对前面提出来的几个部分进行分别研究,并且分割复用其中部分为自己所用,关键是理解思路;

2)将类库中全部的文件和其应该发挥的作用搞明白;

3)登录官网,查看理解这个类库的发展、讨论和现状;

4)反思在图像处理领域应该如何做下去。

[2016年4月7日15:34:25]

首先理解CImg类库的类库特点和代码结构;而后对背景动画进行分析。所有的结果都需要能够独立出来并且方便被复用。

能够直接绘制出"plasma"纹理的界面

动态的圆的界面主要还是来自于随机数



#include "CImg_demo.h"
// Include CImg library header.
#include "CImg.h"
using namespace cimg_library;
#undef min
#undef max
void main()
{
     cimg::info();
     //各类RGB定值
     const unsigned char
         white[]  = { 255, 255, 255 }, black[] = { 0, 0, 0 },     red[] = { 120, 50, 80 },
         yellow[] = { 200, 155, 0 },   green[] = { 30, 200, 70 }, purple[] = { 175, 32, 186 },
         blue[]   = { 55, 140, 185 },  grey[] = { 127, 127, 127 };
     float
         rx = 0, ry = 0, t = 0, gamma = 0, vgamma = 0, T = 0.9f,
         nrx = (float)(2*cimg::crand()),
         nry = (float)(2*cimg::crand());
     int y0 = 2*13;
     //图像显示
     CImg<unsigned char> back(1,2,1,3,10), fore, text, img;//back fore text img都是界面背景
     back.fillC(0,1,0,10,10,235).resize(640,480,1,3,3).get_shared_channel(2).noise(10,1).draw_plasma();//绿宝石界面
      fore.assign(back.width(),50,1,1,0).draw_text(20,y0-5,"** CImg %u.%u.%u Samples **",grey,0,1,24,
     cimg_version/100,(cimg_version/10)%10,cimg_version%10);
     (fore+=fore.get_dilate(3).dilate(3)).resize(-100,-100,1,3);
     cimg_forXY(fore,x,y)
     if (fore(x,y)==127) fore(x,y,0) = fore(x,y,1) = fore(x,y,2) = 1;
     else if (fore(x,y)) {
     const float val = cimg::min(255.0f,7.0f*(y-3));
     fore(x,y,0) = (unsigned char)(val/1.5f);
     fore(x,y,1) = (unsigned char)val;
     fore(x,y,2) = (unsigned char)(val/1.1f);
     }
    
     fore.resize(back,0).draw_image(20,y0+2*13,text|=text.get_dilate(3)>>4);
     //创建显示的窗体
     CImgDisplay disp(back,"CImg Library Samples",0,false,true);
     disp.move((disp.screen_width()-disp.window_width())/2,(disp.screen_height()-disp.window_height())/2);
     img = back; back*=0.15f;
      for (y0+=2*13; !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC(); ) {
           while ( !disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) {
                img*=0.85f; img+=back;
                for (int i = 0; i<60; ++i) {
                    const float
                        mx = (float)(img.width()/2+(img.width()/2-30)*((1-gamma)*std::cos(3*t+rx*i*18.0f*cimg::PI/180) +
                        gamma*std::cos(3*t+nrx*i*18.0f*cimg::PI/180))),
                        my = (float)(img.height()/2+(img.height()/2-30)*((1-gamma)*std::sin(4*t+ry*i*18.0f*cimg::PI/180) +
                        gamma*std::sin(4*t+nry*i*18.0f*cimg::PI/180))),
                        mz = (float)(1.3f + 1.2f*((1-gamma)*std::sin(2*t+(rx+ry)*i*20*cimg::PI/180) +
                        gamma*std::sin(2*t+(nrx+nry)*i*20*cimg::PI/180)));
                    const int j = i%5;
                    //具体画圆
                    img.draw_circle((int)mx,(int)my,(int)(10*mz),j!=0?(j!=1?(j!=2?(j!=3?green:red):yellow):purple):blue,0.2f).
                        draw_circle((int)(mx+4*mz),(int)(my-4),(int)(3*mz),white,0.1f).
                        draw_circle((int)mx,(int)my,(int)(10*mz),black,0.2f,~0U);
                }
                const unsigned char *ptrs = fore.data();
                cimg_for(img,ptrd,unsigned char
                { 
                    const unsigned char val = *(ptrs++);
                    if (val) *ptrd = val; 
}
                //显示菜单条
                int y = disp.mouse_y();
                if (y>=y0 && y<y0+27*13) {
                    y = (y/13)*13+7;
                    for (int yy = y-7; yy<=y+6; ++yy) img.draw_rectangle(0,yy,0,1,img.width()-1,yy,0,1,(unsigned char)(130-15*cimg::abs(yy-y)));
                    img.draw_triangle(2,y-4,2,y+4,8,y,yellow).draw_triangle(img.width()-2,y-4,img.width()-2,y+4,img.width()-8,y,yellow);
                }
                gamma+=vgamma; 
                if (gamma>1) 
                { 
                    gamma = vgamma = 0; 
                    rx = nrx;
                    ry = nry; 
                    nrx=(float)(2*cimg::crand());
                    nry=(float)(2*cimg::crand());
                }
                t+=0.006f; T+=0.005f; if (T>1) { T-=(float)(1+cimg::crand()); vgamma = 0.03f; }
                disp.resize(disp,false).display(img).wait(25);
           }
      }
    
     getchar();
}

使用opencv进行重写

来自为知笔记(Wiz)

时间: 2024-10-17 01:31:48

[-blogs-]Cimg代码初探的相关文章

代码初探-&gt;能耗

将作为一名程序员,进一步确定的目标是成为一个架构师,那么能耗必须考虑. 写代码与能耗的关系不言自明,现在假设将网络视频监控的监控识别算法放在客户端,既不利于算法的保护,也不利于算法的优化,更不利于降低能耗. 谈到能耗,每一台服务器都是吃电器,如果我不是老板,就不考虑耗电的情况,但是如果作为这个公司的一员,也有义务从能耗的角度去写代码. 一个65W的CPU跑一年,需耗电568度电,一度电假定为1.2元,那么一个CPU就需要耗电681.6元,这个价钱可以再买个CPU了. 对于一个1500W的GPU跑

delphi中formatFloat代码初探(在qt下实现floatformat的函数)

由于项目需要,需要在qt下实现floatformat的函数.之前写过一个,但是写得不好.决定重新写一个,参考delphi xe2下的实现.把xe2下的相关代码都看了一遍,xe2的代码思路在这里贴出来.xe2下的代码在system.sysutils下,核心函数是InternalFloatToTextFmt.它有汇编的版本跟纯pascal的版本.汇编看不懂,参考的是纯pascal的版本. 整体流程是: 1)解析format格式化字符串 [delphi] view plain copy Result 

页面定制CSS代码初探:页面变宽 文本自动换行 图片按比缩放

一.初识博客 初写博客,先在设置里选了个喜欢的模板 第一眼就爱上了呢!那极简的风格,我喜欢!!但是,应用后,却发现... 纳尼!模板上右侧那张漂亮的图片呢?!我的怎么什么都没有.没有图片好难看啊,瞬间无爱了,设置里找了下,->博客侧边栏公告 <-,在这里,放了张宽200px的图,好看多了马上,还是有图才不会那么单调~ 二.认识CSS 过了几天,打算写篇博,发现了一个重大的问题,怎么默认的宽度这么窄?那我放图片怎么办,而且,2边留那么多空白不浪费吗,留个5%就够了吧.于是乎,开始了2天的全折腾.

CImg库介绍

转自:http://www.cppprog.com/2009/0424/106.html CImg是一个跨平台的C++的图像处理库,提供了加载.处理.显示.保存等一系列功能,其中的图像处理功能尤其强大.首先,建议先到这里欣赏一下使用CImg代码做的Demo,就是它使我这个没有图像处理经验的童鞋也心动得以致于研究了一星期^_^ 主页地址:http://cimg.sourceforge.net/下载地址:http://cimg.sourceforge.net/download.shtml下载时注意应

LDA进阶

转自:http://blog.csdn.net/hxxiaopei/article/details/8034308 http://blog.csdn.net/huagong_adu/article/details/7937616 代码初探 http://blog.csdn.net/yangliuy/article/details/8457329 yangliuy实现的代码 第一篇:PLSA及EM算法 第二篇:LDA及Gibbs Samping 第三篇:LDA变形模型-Twitter LDA,Ti

Extjs4中的store

Extjs 4引入新的数据包,其中新增了不少新类并对旧有的类作出了修整.使数据包更强大和更容易使用. 本章我们将学习一下内容: 2.1. 概述新特性 Extjs4的数据包引入了如Model类的新特性.同时对Store和Proxy类进行了修整.大部分的修整都是向后兼容的.最大的变化是在Record.Store和Proxy类中.Extjs4的数据包是其中一个与Sencha Touch共享的包. Model是数据包中其中一个最重要的类.它的前身是Record类.现在我们可以通过Model类来代表现实对

iap 详细

附:本文来自IOS6-Tutorias的翻译,本做笔记之用,故语言简练. 一,可用的IAP类型: Non-Consumable:用户只需购买一次,不需要再次购买,即可在多台设备上拥有之(restore技术). Consumable:用户可以购买多次(不限定次数).例如金币. Auto-Renewable Subscriptions:为了收到app更新的内容,用户需要定期支付款项.(目前仅适用于杂志或者新闻类型的app). Free Subscriptions:类似于Auto-Renewable

使用Revel(go)开发网站

Revel很好的利用了Go语言的goroutine,把每一个request都分配到了goroutine里.不用再写一大堆的回调.如果你写过nodejs的话就会深刻的体会到callback hell是什么样子的.正是由于Revel有了goroutine,Revel的性能也有了很大的提升.官网号称请求的吞吐量是Rails的3到10倍.Revel的性能好,在开发方面也提供了非常全面的工具.常用的路由.模板.session.参数解析.等几乎都有,甚至还提供了一个测试框架.而这些东西的开发都是模块化的,也

Servlet&amp;&amp;Jsp 概述

主题 Servlet的作用 构建动态网页 Servlet代码初探 Servlet与其他技术的对比 Jsp的作用 Servlet的作用 Servlet是在web服务器或应用服务器上用来动态生成html的java程序. 起到中间件的作用.将web浏览器或者http客户端与http服务器或者应用程序服务器连接起来.为什么需要它?因为有的应用程序服务器并不支持http,那么所有http客户端都将不能从中获取数据或执行操作,因此,servlet负责彼此交流的桥梁. (1)读取客户发送的显示数据 表单等中的