第一种吧,
每行的字节数一定是四的,
但反色是对图像的每个像素进行,所以循环条件中用ImageWidth
,

解决方案 »

  1.   

    //如果是8位位图文件,有个取巧的办法是直接修改调色板的内容,其他不变,8位的改变调色板的内容实现反色才是正道,改变图像数据是理论上错误的,效果上也是错误的。
    参考 :http://topic.csdn.net/u/20081122/18/07f64cbd-cbe8-465b-bd90-a8f297dbcb37.html
      

  2.   

    严格的说,三个函数没有一个是正确或完美的,首先1的效果始终正确,但只能有50%可能性正确,2是错误的代码,3是很不严格的代码,也不正确。分析:
    1、你所谓的8位色,有两种情况,8位灰度图像或者8位索引图像,两者为什么要区分,就是因为处理方法上不同,你先做个试验,用photoshop分别打开二副彩色图像,然后一副改为灰度,一副改为索引色,你会发现改为索引色后滤镜菜单和调整中的部分菜单都不可以使用,而改为灰度的图像却可以使用。这里的原因就是:对8位灰度图像的处理,不是通过调色板进行的,而是处理正真的数据;对于索引色的处理,是直接改变调色板实现的。 所以,为什么我说1只有50%可能性正确,即在图像为为灰度模式下是正确的。具体可以参考我以前写的:http://topic.csdn.net/u/20070505/16/3399cca4-4499-4438-8a7c-b2722141ba8f.html2、第二种代码是完全错误的,只有当你的图像宽度为4的倍数的时候,效果才有可能正确。其他情况下你会发现图像有一个倾斜线状的变形。因为实际的扫描行始终比宽度大或者等于,这里还是不会出现范围非法内存的情况。3、第三种代码是不严格的,因为他有可能计算了非图像数据,这不是我们希望的。
    就简单的反色来说第一种代码是对资源的严重浪费,两个memcpy过程是浪费时间和空间。
      

  3.   

    但在vc里面,我看过几本vc图像书,没有见过索引图像的介绍,当然也更不知道对索引图像的操作了,在matlab里面是有索引图像的,在vc里面,8位图像即256色位图就叫灰度图像(大家都这么说),它需要有调色板来支持,那么根据您的叙述,灰度图像就变成了索引图像。
    谢谢您指出的代码问题,即可修改。
    您说用memcpy是浪费,那如果您来写的话,这个处理最简洁的代码应该怎么写呢?我刚学图像处理也是刚学vc的新人,希望师兄指点。
      

  4.   

    如果你的意思只是要修改lpDIBBits的话,完全没有必要再申请空间,直接在lpDIBBits上该就可以了,也就是像这样:for()
    for()
    lpSrc=(unsigned char*)lpDIBBits+i*lmageWidth+j; 
    *lpSrc = 255 - *lpSrc;谢谢laviewpbt ,我也收获不少。
      

  5.   

    #define WIDTHBYTES(i)    ((i+31)/32*4)
    LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
    其中bi.biBitCount为图像的位深,256色则为8。此方法可通用不同位深的图像。