首頁 > 軟體

Python圖片批次自動摳圖去背景的程式碼詳解

2022-03-24 13:00:24

今天發現個好東西啊,叫片刻摳圖,是一個線上對圖片自動摳圖去除背景的網站。只要上傳圖片,就可以自動把背景去掉把目標物件摳出來。

不管是動物、汽車或各種產品,還是人物,都可以全自動做到令人驚豔的摳圖效果!而且還說可以做到髮絲級 AI 自動摳圖,作為一個頭發存留不多的程式設計師,突然莫名感覺到一絲來自這個世界的惡意。

這個摳圖有什麼用?比如可以把人物摳出來換個背景:

也可以把產品摳出來做成新的商品宣傳圖:(做電商的朋友肯定懂)

這麼好用的東西,現在最關鍵的是:完全免費!

emmmmmm,這個訊息被我的幾十個前任女友知道了,她們紛紛發來照片,要我給她把照片背景給去掉,把她美美的人像給摳出來,之後好換上馬爾地夫的背景。

這麼多的圖片要一張張傳上去,再下載回來,同樣的事情做幾十遍那我肯定不會做的。

那麼,必須要寫個 Python 自動化指令碼程式來搞定了。

說幹就幹,二話不說就掏出網頁自動化的神器Selenium,寫簡單幾行程式碼:

"""
Selenium是第三方庫,需要先安裝,在Teminal裡執行:pip install selenium
驅動程式 chromedriver 需要根據瀏覽器 chrome 的版本下載
有問題的可以加我:youbafu  (全網統一id)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

s = Service(r'D:driverchromedriver.exe')
# 初始化瀏覽器為chrome瀏覽器
browser = webdriver.Chrome(service=s)
# 開啟 片刻摳圖
browser.get(r'https://www.pickwant.com')

就完成了自動開啟網頁:

但這是遠遠不夠的,我們需要實現自動上傳圖片,然後自動下載。

通過幾次手動操作得出規律,我們只要進入到編輯介面

然後迴圈執行以下步驟:

1、點選網頁右上角的重新上傳按鈕。

2、選擇要上傳的圖片,點開啟按鈕。

3、等幾秒摳好圖後,點網頁右上角下載按鈕。

4、彈出對話方塊後,再點確認下載就會自動儲存圖片。

就可以依次把資料夾裡的前女友們的圖片完成自動摳圖了。

要做出自動化指令碼,接下來就是找到這些按鈕,然後模擬點選就可以了。在重新下載按鈕上點滑鼠右鍵,在彈出的選單中點檢查,彈出了網頁的元素檢視介面,再重複操作一次,就定位到了這個按鈕的網頁程式碼:

可以看到重新上傳是個 span ,這裡可以取它的上級 div,它的class是border_wrap upload_wrap,那麼就可以寫程式碼定位到這個元素,然後執行click()操作了。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

s = Service(r'D:driverchromedriver.exe')
# 初始化瀏覽器為chrome瀏覽器
browser = webdriver.Chrome(service=s)
# 開啟 片刻摳圖
browser.get(r'https://www.pickwant.com/#/editor')
time.sleep(1)
# 定位到 重新上傳 按鈕
upload = browser.find_element(By.CSS_SELECTOR, '.border_wrap.upload_wrap')
upload.click()

這裡要特別說明的是,根據 CSS 的基本語法,id用#表示,class用.來表示,如果中間有空格也是用.來拼接,下級標籤用>來拼接。

<div data-v-0373fdbc="" class="border_wrap upload_wrap"></div>

對於這樣的 div 標籤,其class是 border_wrap upload_wrap ,所以 By.CSS_SELECTOR 的查詢元素的引數就是 ‘.border_wrap.upload_wrap’ 。

程式碼執行後,彈出一個選擇檔案的對話方塊:

這時候問題來了,這個對話方塊是 Windows 系統級別的,不受Selenium控制,怎麼辦?

不要慌,這難不倒霸夫老師,既然是 Windows 系統彈窗,那總得受系統控制吧!

那就祭出 pywin32 庫來對付它,在終端命令列(Terminal)裡輸入命令安裝庫:

pip install pywin32

然後再開啟檢視 Windows 視窗資訊的神器spy++,拿到視窗的類名和層次結構關係,就可以寫出以下的自動選擇檔案並點選按鈕的函數程式碼了:

import win32con # win32庫裡包含了很多模組
import win32gui # 這裡匯入具體用到的模組
def 上傳圖片(檔案路徑):
    dialog = win32gui.FindWindow('#32770', u'開啟')  # 對話方塊
    ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
    ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
    Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)  # 上面三句依次尋找物件,直到找到輸入框Edit物件的控制程式碼
    button = win32gui.FindWindowEx(dialog, 0, 'Button', None)  # 開啟按鈕
    time.sleep(0.5)
    win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 檔案路徑)  # 往輸入框輸入絕對地址
    time.sleep(0.5)
    win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)  # 點 開啟 按鈕
    time.sleep(5)

先寫好這個函數備用,等下要上傳哪張圖片,只要呼叫函數時把圖片的檔案路徑作為引數傳入,就可以完成目標了。

上傳圖片後,只要稍等一兩秒就自動完成摳圖了。這時候再點網頁右上角下載按鈕,等彈出對話方塊後,再點確認下載就會自動儲存圖片。

前面我們學習了定位元素的方法了,再定位這兩個按鈕對我們來說不是什麼困難了。

但是,你都能堅持看到這裡了,霸夫老師必須要教你個更牛X的更方便的技巧了:

下載按鈕上點滑鼠右鍵,在彈出的選單中點檢查,彈出了網頁的元素檢視介面,再重複操作一次,就定位到了這個按鈕的網頁程式碼。然後在它的上一級的這個div標籤上點滑鼠右鍵,選擇Copy,再選擇Copy selector

然後回到python程式碼編輯視窗,貼上就可以獲得準確的定位引數:

#app > div > div:nth-child(1) > div.col-md-12.wonx_row.top_bar > div.border_wrap.download_wrap

這樣就省去了辛辛苦苦去理解和轉化引數,大大提高效率,接下來就可以輕鬆寫出定位元素和點選的程式碼:

download = browser.find_element(By.CSS_SELECTOR, '#app > div > div:nth-child(1) > div.col-md-12.wonx_row.top_bar > div.border_wrap.download_wrap')
download.click() # 點選 下載
time.sleep(0.5)
comfirm = browser.find_element(By.CSS_SELECTOR, '#app > div > div.container > div.dialog-content > div > div.download_wrap')
comfirm.click()  # 點選 確認下載
time.sleep(1)

單張圖片的上傳和下載流程都寫完了,接下來要寫個獲取資料夾下所有圖片的函數,來實現依次把每個前任的圖片都完成摳圖的任務。

我把她們的照片都放在電腦的 E: 盤下的前任女友這個資料夾裡,那麼只要讀取這個資料夾下的所有圖片,依次執行執行一遍上傳和下載操作就可以了。

資料夾路徑 = r'E:前任女友'
names = os.listdir(資料夾路徑)  # 列舉出該目錄下所有的檔名
for name in names:
    path = os.path.join(資料夾路徑, name)  # 拼接出圖片完整路徑
    # 點選重新上傳() # 等待封裝
    上傳圖片(path)
    # 點選下載() # 等待封裝

所有的邏輯都理清楚了,模組也基本寫好了,接下來就把程式碼整合一下,來看完整程式碼:

"""
片刻摳圖
圖片批次自動摳圖去背景
作者:有霸夫
有問題請加vx:youbafu
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import win32con
import win32gui
import os

s = Service(r'D:driverchromedriver.exe')
# 初始化瀏覽器為chrome瀏覽器
browser = webdriver.Chrome(service=s)
# 開啟 片刻摳圖
browser.get(r'https://www.pickwant.com')
time.sleep(1)
browser.get(r'https://www.pickwant.com/#/editor')
time.sleep(2)
def 點選重新上傳():
    while True:
        try:
            # 定位到 重新上傳 按鈕
            upload = browser.find_element(By.CSS_SELECTOR, '.border_wrap.upload_wrap')
            upload.click()
        except:
            print('請先掃描登入或完成驗證碼識別')
        else:
            print('點選 重新上傳')
            break
        finally:
            time.sleep(1)
def 上傳圖片(檔案路徑):
    dialog = win32gui.FindWindow('#32770', u'開啟')  # 對話方塊
    ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
    ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
    Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)  # 上面三句依次尋找物件,直到找到輸入框Edit物件的控制程式碼
    button = win32gui.FindWindowEx(dialog, 0, 'Button', None)  # 開啟按鈕
    if Edit is not None and button is not None:
        time.sleep(0.5)
        win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 檔案路徑)  # 往輸入框輸入絕對地址
        print('上傳:', 檔案路徑)
        win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)  # 點 開啟 按鈕
        time.sleep(5)
def 點選下載():
            download = browser.find_element(By.CSS_SELECTOR, '.border_wrap.download_wrap')
            download.click()
            time.sleep(0.5)
            confirm = browser.find_element(By.CSS_SELECTOR, '.dialog-content>.content_wrap>.download_wrap')
            confirm.click()
            print('點選 下載')
資料夾路徑 = r'E:前任女友'
names = os.listdir(資料夾路徑)  # 列舉出該目錄下所有的檔名
for name in names:
    path = os.path.join(資料夾路徑, name)  # 拼接出圖片完整路徑
    點選重新上傳()
    上傳圖片(path)
    點選下載()
print('恭喜!全部完成')

在完整程式碼中加入了例外處理,如果遇到需要掃碼登入或者驗證碼,手動操作一下,還會繼續執行下去的。

到此這篇關於Python圖片批次自動摳圖去背景的文章就介紹到這了,更多相關Python批次自動摳圖去背景內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com