跳至內容

Python 影像庫/陰影

來自華夏公益教科書,開放的書籍,為開放的世界

陰影是強調影像的一種常見方式。

建立陰影

[編輯 | 編輯原始碼]

陰影可以透過獲取一個簡單的實心矩形(通常為黑色或灰色,但你也可以使用彩色陰影)並重復對其應用 ImageFilter BLUR 濾鏡來建立。此濾鏡使用 5×5 核,因此一次迭代不會產生平滑的模糊效果。你可以透過實驗找到適合你目的的最佳迭代次數。

def makeShadow(image, iterations, border, offset, backgroundColour, shadowColour):
    # image: base image to give a drop shadow
    # iterations: number of times to apply the blur filter to the shadow
    # border: border to give the image to leave space for the shadow
    # offset: offset of the shadow as [x,y]
    # backgroundCOlour: colour of the background
    # shadowColour: colour of the drop shadow
    
    #Calculate the size of the shadow's image
    fullWidth  = image.size[0] + abs(offset[0]) + 2*border
    fullHeight = image.size[1] + abs(offset[1]) + 2*border
    
    #Create the shadow's image. Match the parent image's mode.
    shadow = Image.new(image.mode, (fullWidth, fullHeight), backgroundColour)
    
    # Place the shadow, with the required offset
    shadowLeft = border + max(offset[0], 0) #if <0, push the rest of the image right
    shadowTop  = border + max(offset[1], 0) #if <0, push the rest of the image down
    #Paste in the constant colour
    shadow.paste(shadowColour, 
                [shadowLeft, shadowTop,
                 shadowLeft + image.size[0],
                 shadowTop  + image.size[1] ])
    
    # Apply the BLUR filter repeatedly
    for i in range(iterations):
        shadow = shadow.filter(ImageFilter.BLUR)

    # Paste the original image on top of the shadow 
    imgLeft = border - min(offset[0], 0) #if the shadow offset was <0, push right
    imgTop  = border - min(offset[1], 0) #if the shadow offset was <0, push down
    shadow.paste(image, (imgLeft, imgTop))

    return shadow

首先,讓我們忽略最後一步,專注於陰影。讓我們看看不同迭代次數的結果。邊框設定為 8,背景為白色,陰影為 0x444444 灰色。初始影像為 30×30 畫素。

1 次迭代 2 次迭代 3 次迭代 5 次迭代 10 次迭代

請注意,陰影始終包含在影像邊界內 - 這是因為藍色濾鏡“碰到”影像邊界造成的。如果邊框更大,你會看到在大量迭代次數下模糊會散開。

現在,我們可以新增最後一部分並嘗試一下。結果如下。此影像使用了 [3,3] 的偏移量,進行了 3 次迭代,顏色與之前相同。

原始影像(SVG 被製作成了矩形 PNG) 帶有陰影的最終影像

生成模糊陰影所需的計算量很大,特別是對於大型影像或多次迭代,但相同的陰影可以重複用於相同大小的任何影像。因此,如果你要建立許多相同大小的影像塊,則一次計算陰影並將其重複用於每個影像將是有益的。

你還可以透過識別陰影的中心將是陰影顏色的平面填充來加快陰影的計算 - 只需計算邊緣即可。較亮邊框向內延伸的距離取決於迭代次數。對於大型影像,此更改將問題從影像大小的二次方(即寬度加倍,時間乘以四倍)減少到線性(寬度加倍,時間加倍),但對於圖示來說不太可能產生很大影響。

處理非矩形影像

[編輯 | 編輯原始碼]

新增透明度

[編輯 | 編輯原始碼]
華夏公益教科書