返回列表 回复 发帖
发一个用GSP扫的图片,并用图象软件处理的浮雕效果,以示对大家的支持。
1109131952625d608e9f7c4da6.jpg
2011-11-24 23:00
再换一个看看:
捕获.JPG
22# 榕坚

比较接近了
20# changxde


看方法好象觉得很容易,但涉及泛函中的卷积又要涉及到积分函数,头大。
彩色的弄了几张,还没有掌握色彩调节。只有这个效果还不错。
10.JPG
找到一个原理比较简单的算法:
实现图像浮雕效果的一般原理是,将图像上每个像素点与其对角线的像素点形成差值,使相似颜色值淡化,不同颜色值突出,从而产生纵深感,达到浮雕的效果,具体的做法是用处于对角线的2个像素值相减,再加上一个背景常数,一般为128而成。这种算法的特点是简单快捷,缺点是不能调节图像浮雕效果的角度和深度。

    用Photoshop实现图像浮雕效果,可以任意调节浮雕角度和深度(2个像素点的距离),还可以调整浮雕像素差值的数量。其基本算法原理和一般浮雕效果相同,但是具体做法不一样:对每个要处理的像素点,首先按照浮雕角度和深度计算处2个相应点的位置,然后计算这2个位置的颜色值,并使之形成差值,再乘上浮雕差值数量百分比,最后加上128的背景色。注意,这里计算的2个相应点是逻辑点,而不是实际的像素点,比如实现一个45度角,深度为3的图像浮雕效果,对每个像素点P(x, y),其对应的2个逻辑点的位置分别是P0(x - 3 * 0.7071 / 2, y - 3 * 0.7071 / 2)和P1(x + 3 * 0.7071 / 2, y + 3 * 0.7071 / 2),显然,对于这样的2个逻辑点,是不能直接从图像中找到其对应的像素点的,如果简单地对其四舍五入处理,将会造成大量的,由不同角度和深度而形成的相同的浮雕效果,这可不是我们想要的结果,而且使浮雕角度和深度参数失去了它原本的意义。为此,必须对原始图像按浮雕角度和深度进行缩放后,再对每个像素点进行浮雕效果处理,完毕再缩放回原图的大小,从而完成整个浮雕效果过程。下面是我经过反复试验后,写的Photoshop浮雕效果实现过程代码:

view plaincopy to clipboardprint?
01.过程定义:  
02.  
03.  // 灰色浮雕。参数:  
04.  //   Dest输出图,Source原图,Data自身操作图像  
05.  //   Angle 角度, Size 长度, Num 像素数量百分比  
06.  //   Callback回调函数,返回True终止操作,CallbackData回调函数参数地址  
07.  procedure ImageGraySculpture(var Data: TImageData;  
08.    Angle: Single; Size: LongWord; Num: LongWord = 100); overload;  
09.    {$IF RTLVersion >= 17.00}inline;{$IFEND}  
10.  procedure ImageGraySculpture(var Dest: TImageData; const Source: TImageData;  
11.    Angle: Single; Size: LongWord; Num: LongWord = 100); overload;  
12.    {$IF RTLVersion >= 17.00}inline;{$IFEND}  
13.  // 无效参数或者被回调函数终止操作返回False。  
14.  function ImageGraySculpture(var Dest: TImageData; const Source: TImageData;  
15.    Angle: Single; Size: LongWord; Num: LongWord;  
16.    Callback: TImageAbort; CallbackData: Pointer): Boolean; overload;  
17.  
18.代码实现:  
19.  
20.procedure GetSrcColor;  
21.asm  
22.    push      edx           // edx = x  
23.    push      ecx           // ecx = y  
24.    mov       esi, ecx      // esi = y / 256 * Data.Stride +  
25.    mov       eax, edx      //   x / 256 * 4 + Data.Scan0  
26.    sar       esi, 8  
27.    sar       eax, 8  
28.    shl       eax, 2  
29.    imul      esi, [ebx].TImageData.Stride  
30.    add       esi, eax  
31.    add       esi, [ebx].TImageData.Scan0  
32.    call      GetBilinearColor  
33.    pop       ecx           // return eax = mm0 = ARGB  
34.    pop       edx  
35.end;  
36.  
37.procedure GraySculpture(x, y, xDelta, yDelta, Num: Integer); pascal;  
38.var  
39.  width, height: Integer;  
40.  dstOffset: Integer;  
41.  colorBuf: TARGBQuadW;  
42.  data: TImageData;  
43.asm  
44.    mov       dstOffset, ebx  
45.    lea       ebx, data  
46.    mov       [ebx].TImageData.Scan0, esi  
47.    shl       ecx, 2  
48.    add       eax, ecx        // Stride = srcOffset + width * 4  
49.    mov       [ebx].TImageData.Stride, eax  
50.    shl       ecx, 6  
51.    add       ecx, x  
52.    mov       width, ecx      // width = width * 256 + x  
53.    shl       edx, 8  
54.    add       edx, y  
55.    mov       height, edx     // height = height * 256 + y  
56.    movd      mm6, Num  
57.    punpcklwd mm6, mm6  
58.    punpcklwd mm6, mm6        // mm6 = 00 Num 00 Num 00 Num 00 Num  
59.    pxor      mm7, mm7        // mm7 = 00 00 00 00 00 00 00 00  
60.    mov       ecx, y          // for (; y < Height; y += 256)  
61.@@yLoop:                      // {  
62.        mov         edx, x          //   for (; x < Width; x += 256  
63.@@xLoop:                      //   {  
64.    add       ecx, yDelta     //     y1 = y + yDelta  
65.    add       edx, xDelta     //     x1 = x + xDelta  
66.    call      GetSrcColor     //     mm0 = 00 00 00 00 A1 R1 G1 B1  
67.    punpcklbw mm0, mm7        //     mm0 = 00 A1 00 R1 00 G1 00 B1  
68.    movq      ColorBuf, mm0   //     ColorBuf = mm0  
69.    sub       ecx, yDelta     //     y0 = y - yDelta  
70.    sub       edx, xDelta     //     x0 = x - xDelta  
71.    call      GetSrcColor     //     mm0 = 00 00 00 00 A0 R0 G0 B0  
72.    punpcklbw mm0, mm7        //     mm0 = 00 A0 00 R0 00 G0 00 B0  
73.    psubsw    mm0, ColorBuf   //     mm0 = A0-A1 R0-R1 G0-G1 B0-B1  
74.    psllw     mm0, 7          //     mm0 = mm0 * 128 * Num / 65536  
75.    pmulhw    mm0, mm6  
76.    paddsw    mm0, qword ptr ArgbTable[128*8]//     mm0 = A+128 R+128 G+128 B+128  
77.    packuswb  mm0, mm7        //     mm0 = 00 00 00 00 A R G B  
78.    mov       al, [edi].TARGBQuad.Alpha  
79.    movd      [edi], mm0      //     *edi = mm0  
80.    mov       [edi].TARGBQuad.Alpha, al  
81.    add       edi, 4          //     edi += 4  
82.        add         edx, 256  
83.    cmp       edx, Width  
84.    jl        @@xLoop         //   }  
85.    add       ecx, 256  
86.    add       edi, dstOffset  
87.    cmp       ecx, Height  
88.    jl        @@yLoop         // }  
89.    emms  
90.end;  
91.  
92.function ImageGraySculpture(var Dest: TImageData; const Source: TImageData;  
93.  Angle: Single; Size: LongWord; Num: LongWord;  
94.  Callback: TImageAbort; CallbackData: Pointer): Boolean;  
95.var  
96.  x, y, Radius: Integer;  
97.  xDelta, yDelta: Integer;  
98.  dst, src: TImageData;  
99.begin  
100.  Result := False;  
101.  if ImageEmpty(Dest) or ImageEmpty(Source) or (Size = 0) then  
102.    Exit;  
103.  Radius := (Size + 1) shr 1;        // 图像边框扩展半径  
104.  Angle := PI * Angle / 180;  
105.  Size := Size shl 8;                // Size = Size * 256  
106.  Num := (Num shl 9) div 100;        // Num *= 5.12 转换为2的幂  
107.  xDelta := Round(Cos(Angle) * Size);  
108.  yDelta := Round(Sin(Angle) * Size);  
109.  x := (Radius shl 8) - (xDelta div 2);  
110.  y := (Radius shl 8) - (yDelta div 2);  
111.  if @Dest <> @Source then  
112.    CopyAlpha(Dest, Source);  
113.  GetExpandData(Dest, Source, Radius, dst, src);  
114.  try  
115.    if Assigned(Callback) then  
116.      Result := ExecuteAbort(dst, src, @GraySculpture,  
117.        [x, y, xDelta, yDelta, Num], Callback, CallbackData)  
118.    else  
119.      Result := ExecuteProc(dst, src, @GraySculpture, [x, y, xDelta, yDelta, Num]);  
120.  finally  
121.    FreeImageData(src);  
122.  end;  
123.end;  
124.  
125.procedure ImageGraySculpture(var Dest: TImageData; const Source: TImageData;  
126.  Angle: Single; Size: LongWord; Num: LongWord);  
127.begin  
128.  ImageGraySculpture(Dest, Source, Angle, Size, Num, nil, nil);  
129.end;  
130.  
131.procedure ImageGraySculpture(var Data: TImageData;  
132.  Angle: Single; Size: LongWord; Num: LongWord);  
133.begin  
134.  ImageGraySculpture(Data, Data, Angle, Size, Num, nil, nil);  
135.end;
这个我也看不懂。
我觉得抓住“相邻2个像素值相减,再加上一个背景常数。”这一点就可以了。
新思想完成下图:
Mps.jpg
2011-11-26 10:07

学习PS浮雕效果MJ.gsp (16.82 KB)

28# changxde
恭喜常老师,此图已达浮雕效果,而且明暗位置完全符合光照原理。
28# changxde


常老师的这幅图是用等势线弄的吧?
返回列表