user-0 提问: 关于位运算做除法的问题

回复:
user: user-1
content: #include <xmmintrin.h> __m128 ConvertIntToFloatColor(__m128 scaleFactor, int r, int g, int b, int a) {     __m128i intColor = _mm_set_epi32(a, b, g, r);     __m128 floatColor = _mm_cvtepi32_ps(intColor);     floatColor = _mm_mul_ps(floatColor, scaleFactor);     return floatColor; }  __m128 AlphaBlend(__m128 srcColor, __m128 dstColor, __m128 oneOneOneZero, __m128 zeroZeroZeroOne) {     __m128 srcAlpha = _mm_shuffle_ps(srcColor, srcColor, _MM_SHUFFLE(3, 3, 3, 3));     __m128 dstAlpha = _mm_shuffle_ps(dstColor, dstColor, _MM_SHUFFLE(3, 3, 3, 3));     __m128 one = _mm_set1_ps(1.0f);     __m128 oneMinusSrcAlpha = _mm_sub_ps(one, srcAlpha);     __m128 outAlpha = _mm_add_ps(srcAlpha, _mm_mul_ps(dstAlpha, oneMinusSrcAlpha));     __m128 blended = _mm_add_ps(_mm_mul_ps(srcColor, srcAlpha),                                 _mm_mul_ps(_mm_mul_ps(dstColor, dstAlpha), oneMinusSrcAlpha));     blended = _mm_and_ps(blended, oneOneOneZero);     outAlpha = _mm_and_ps(outAlpha, zeroZeroZeroOne);      return _mm_or_ps(blended, outAlpha); }  void ConvertFloatToIntColor(__m128 floatColor, __m128 scaleFactor, int* r, int* g, int* b, int* a) {     floatColor = _mm_mul_ps(floatColor, scaleFactor);     __m128i intColor = _mm_cvtps_epi32(floatColor);     int* i = (int*)&intColor;     *r = i[0];     *g = i[1];     *b = i[2];     *a = i[3]; }  void TestBlend() {     __m128 oneOneOneZero;     __m128 zeroZeroZeroOne;     int* oneOneOneZeroPtr = (int*)&oneOneOneZero;     int* zeroZeroZeroOnePtr = (int*)&zeroZeroZeroOne;     oneOneOneZeroPtr[0] = 0xffffffff;     oneOneOneZeroPtr[1] = 0xffffffff;     oneOneOneZeroPtr[2] = 0xffffffff;     oneOneOneZeroPtr[3] = 0x00000000;     zeroZeroZeroOnePtr[0] = 0x00000000;     zeroZeroZeroOnePtr[1] = 0x00000000;     zeroZeroZeroOnePtr[2] = 0x00000000;     zeroZeroZeroOnePtr[3] = 0xffffffff;     __m128 scaleFactor0 = _mm_set1_ps(1.0f / 255.0f);     __m128 scaleFactor1 = _mm_set1_ps(255.0f);          __m128 red = ConvertIntToFloatColor(scaleFactor0, 255, 0, 0, 255);     __m128 green = ConvertIntToFloatColor(scaleFactor0, 0, 255, 0, 128);     __m128 color = AlphaBlend(green, red, oneOneOneZero, zeroZeroZeroOne);     int r, g, b, a;     ConvertFloatToIntColor(color, scaleFactor1, &r, &g, &b, &a);     printf("r %d, g %d, b %d, a %d\n", r, g, b, a); }  使用SSE计算的版本，注意两个缩放系数scaleFactor0和scaleFactor1， 因为是8bit转成的浮点数，所以scaleFactor0是1.0f / 255.0f, 而 scaleFactor1 是 255.0f

user: user-1
content: 这里不应该用正片叠底，用第一个公式就行了。 原始图片只有RGB三个通道，这是不够的，需要添加alpha通道。 比如RGB(204,224,236)，添加alpha通道后就是RGBA(204,224,236,128)，此时alpha通道是128，也就是50%透明，然后套用第一个公式。 建议计算时将所有定点数转成0.0~1.0浮点数来计算，这样通用性高，色彩格式不仅仅只有8bit还有16bit、4bit等，全转成浮点数来计算只要修改一下色彩转换的代码就可以通用了

user: user-0
content: 多谢各位，赵老师的资料收藏了，资料挺好，就是最近没什么心情看，年底各种破事，等忙完这段再看  引用 16 楼 zhao4zhong1 的回复:PHOTOSHOP图层混合模式的计算公式 http://www.360doc.com/content/14/0520/17/636843_379403237.shtml

user: user-2
content: PHOTOSHOP图层混合模式的计算公式 http://www.360doc.com/content/14/0520/17/636843_379403237.shtml

user: user-2
content: http://image.baidu.com/i?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=Photoshop%20%E5%9B%BE%E5%B1%82%E8%BF%90%E7%AE%97

user: user-2
content: 引用 13 楼 fengswd 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 fengswd 的回复:] [quote=引用 9 楼 lm_whales 的回复:] 这个不需要这么麻烦吧,用alpha 通道处理就是了  好像是这个思路，但是通道只能解决一个像素点啊，它不能细分到红、绿、蓝各个颜色的处理撒。就像上面，白色的部分是rgb(255,255,255)，被处理后变成了RGB(204,224,236),变成了淡蓝色，alpha应该是不能做到这一点的吧？[/quote] 搜索一下PhotoShop图层选项、模式：正片叠底、……[/quote]  好像很难的样子啊，不太懂，以后再琢磨[/quote] 今日事，今日毕。 http://www.baidu.com/s?wd=Photoshop%20%E5%9B%BE%E5%B1%82%E8%BF%90%E7%AE%97&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_pq=c181593800000170&rsv_t=7f09kHnmWHnAsTHVETDUiBOrKPGJ3HqN7KQ6LXAncWU7wgoEJjgL4cp8az9feBqLcQBq&inputT=21915

user: user-0
content: 引用 11 楼 zhao4zhong1 的回复:[quote=引用 10 楼 fengswd 的回复:] [quote=引用 9 楼 lm_whales 的回复:] 这个不需要这么麻烦吧,用alpha 通道处理就是了  好像是这个思路，但是通道只能解决一个像素点啊，它不能细分到红、绿、蓝各个颜色的处理撒。就像上面，白色的部分是rgb(255,255,255)，被处理后变成了RGB(204,224,236),变成了淡蓝色，alpha应该是不能做到这一点的吧？[/quote] 搜索一下PhotoShop图层选项、模式：正片叠底、……[/quote]  好像很难的样子啊，不太懂，以后再琢磨

user: user-3
content: 感觉很热闹的样子

user: user-0
content: 引用 9 楼 lm_whales 的回复:这个不需要这么麻烦吧,用alpha 通道处理就是了  好像是这个思路，但是通道只能解决一个像素点啊，它不能细分到红、绿、蓝各个颜色的处理撒。就像上面，白色的部分是rgb(255,255,255)，被处理后变成了RGB(204,224,236),变成了淡蓝色，alpha应该是不能做到这一点的吧？

user: user-4
content: 这个不需要这么麻烦吧,用alpha 通道处理就是了

user: user-0
content: 引用 6 楼 yaj_4010 的回复:楼主，不明白你是如何得到1.7这个数值的，但是想实现图中的效果是可以的，我以前实现过一个将选择的部分颜色变暗或者渐变的效果图，方法如下：首先要确定图片区域的范围， 然后在吧这个范围中的颜色值以一定的比例重画，已达到这个效果，这是一中方法，另一种方法是用两张或者多种以实现不同的效果。希望对楼主有点提示作用  你说的这个方法是提取像素然后设置新值最后重新设置回去吧？这样效果达到了，可是太慢了，就上图这么大小，框选的部分显示出来得1秒钟。鼠标框选就要即时反应出来，pdf估计是用其他的思路实现的。

user: user-2
content: 引用 10 楼 fengswd 的回复:[quote=引用 9 楼 lm_whales 的回复:] 这个不需要这么麻烦吧,用alpha 通道处理就是了  好像是这个思路，但是通道只能解决一个像素点啊，它不能细分到红、绿、蓝各个颜色的处理撒。就像上面，白色的部分是rgb(255,255,255)，被处理后变成了RGB(204,224,236),变成了淡蓝色，alpha应该是不能做到这一点的吧？[/quote] 搜索一下PhotoShop图层选项、模式：正片叠底、……

user: user-5
content: 引用 楼主 fengswd 的回复:被除数是个小于255的整数，除数是个小数比如1.7，用位运算得到结果，要求不能使用移位运算，也就是说只能用与、或、非、异或来完成，有没有这样的算法？小弟求教，越简单越好，算法越精辟越好，结果满意的话再追加50分  哪里出的这种问题。。。。尼玛不位移分解个屁，用算数位运算来做，这不坑爹么

user: user-0
content: 引用 1 楼 user-7 的回复:怎么感觉象是数字电路，只能帮顶了  多谢

user: user-6
content: 另外计算机的中的乘除都是可以用加减来实现的，这个要楼主去找一本操作系统的书去好好的复习一下如何用加减法实现乘除了

user: user-6
content: 楼主，不明白你是如何得到1.7这个数值的，但是想实现图中的效果是可以的，我以前实现过一个将选择的部分颜色变暗或者渐变的效果图，方法如下：首先要确定图片区域的范围， 然后在吧这个范围中的颜色值以一定的比例重画，已达到这个效果，这是一中方法，另一种方法是用两张或者多种以实现不同的效果。希望对楼主有点提示作用

user: user-7
content: 怎么感觉象是数字电路，只能帮顶了

user: user-0
content: 引用 3 楼 nadleeh123 的回复:[quote=引用 楼主 fengswd 的回复:] 被除数是个小于255的整数，除数是个小数比如1.7，用位运算得到结果，要求不能使用移位运算，也就是说只能用与、或、非、异或来完成，有没有这样的算法？小弟求教，越简单越好，算法越精辟越好，结果满意的话再追加50分   哪里出的这种问题。。。。尼玛不位移分解个屁，用算数位运算来做，这不坑爹么[/quote]  我这不就是问一下有没有这样的运算么？ 还是把问题贴出来吧，   这是PDF文档里截的一幅图。图里蓝色的选择框是鼠标框选时的样子。如果用BiltBlt函数来做这个图形的话，可以是可以，但是我看了一下颜色的rgb值，发现被覆盖的部分是原像素颜色值除以1.7。但是BitBlt等函数的光栅操作只能是与、或、非，异或。所以就想知道到底怎么实现这样的选择框，其实类似的选择框在很多软件里都很常见，比如qq的截图功能。求这位大神告诉我办法，如果成功的话送再送上100分