這期內容當中小編將會給大家?guī)碛嘘PServerless如何實現(xiàn)圖片壓縮與水印,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
專注于為中小企業(yè)提供成都網(wǎng)站制作、網(wǎng)站建設服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)??h免費做網(wǎng)站提供優(yōu)質的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉變。
在實際生產(chǎn)中,用戶上傳圖片是非常常見的行為,無論是做一個相冊系統(tǒng),還是發(fā)布文章中帶有圖片,可以說圖片和Web服務是非常緊密的了。但是圖片所占用的空間,以及圖片的大小等又都是不參差不齊的,同時有些網(wǎng)站的圖片在上傳之后,可能被其他平臺或者開發(fā)者采集并且盜用,這個時候,很多人的做法是在圖片上傳的時候,進行圖像壓縮、標準化以及添加水印,但是這一套流程往往又比較占用資源,尤其是大量大尺寸的圖片產(chǎn)生時。那么在Serverless架構下,是否有一種方法,可以對圖像的壓縮與水印實現(xiàn)"一條龍"服務,而且不會因為用戶量比較多,而影響用戶整體體驗呢?
在前言部分說到,傳統(tǒng)的圖像處理方法,會比較占用資源,讓服務器壓力比較大,甚至會影響用戶體驗:
那么我們是否可以通過Serverless架構,實現(xiàn)一個異步處理流程?
所謂的異步處理流程就是,用戶直接上傳圖片到對象存儲,直接將圖片等資源進行持久化,然后通過對象存儲相關的觸發(fā)器,觸發(fā)指定函數(shù),函數(shù)進行圖像壓縮以及圖像水印等相關處理,再次進行持久化。
以相冊系統(tǒng)為例:用戶上傳圖片之后,系統(tǒng)進行壓縮以及水印并生成縮略圖,存儲到對象存儲中,當用戶瀏覽圖片列表時,展示帶有水印的縮略圖,可以大大提升加載速度,水印可以看作圖像的一種版權保護,當用戶點擊圖片查看原圖時,可以為用戶展示原始圖片。這樣既能保證原圖的存在,就可以提高瀏覽列表等的速度,也具備初步的版權保護能力。
圖像壓縮部分,在這里只用圖像的大小作為壓縮依據(jù),除此之外還可以對圖像的質量進行處理。
單以尺寸進行壓縮處理,可以看作是將一個image
對象和寬度傳入,通過resize
方法進行大小的調整,實現(xiàn)壓縮功能。
def compressImage(image, width): height = image.size[1] / (image.size[0] / width) return image.resize((int(width), int(height)))
圖像水印部分采用的是文字水印,除了文字水印還可以考慮使用圖片水印等。
此處為了將水印放在圖像的右下角,并且恰好不超出圖像范圍,進行了每個字符大小的獲?。?/p>
height = [] width = [] for eveStr in watermarkStr: thisWidth, thisHeight = drawImage.textsize(eveStr, font) height.append(thisHeight) width.append(thisWidth)
通過這樣處理之后,得到的height
列表就是所有即將水印文字的高度,width
列表是所有即將水印文字的寬度。此處要將水印放在右下角只需要在圖片整體高度上減去height
列表最大值,圖片整體寬度基礎上減去width
列表的總和即可:
def watermarImage(image, watermarkStr): txtImage = Image.new('RGBA', image.size, (0, 0, 0, 0)) font = ImageFont.truetype("Brimborion.TTF", 40) drawImage = ImageDraw.Draw(txtImage) height = [] width = [] for eveStr in watermarkStr: thisWidth, thisHeight = drawImage.textsize(eveStr, font) height.append(thisHeight) width.append(thisWidth) drawImage.text((txtImage.size[0] - sum(width) - 10, txtImage.size[1] - max(height) - 10), watermarkStr, font=font, fill=(255, 255, 255, 255)) return Image.alpha_composite(image, txtImage)
通過函數(shù)的事件描述,可以確定騰訊云函數(shù)的對象存儲觸發(fā)器事件結果為:
{ "Records": [ { "cos": { "cosSchemaVersion": "1.0", "cosObject": { "url": "http://testpic-1253970026.cos.ap-chengdu.myqcloud.com/testfile", "meta": { "x-cos-request-id": "NWMxOWY4MGFfMjViMjU4NjRfMTUyMV8yNzhhZjM=", "Content-Type": "" }, "vid": "", "key": "/1253970026/testpic/testfile", "size": 1029 }, "cosBucket": { "region": "cd", "name": "testpic", "appid": "1253970026" }, "cosNotificationId": "unkown" }, "event": { "eventName": "cos: ObjectCreated:Post", "eventVersion": "1.0", "eventTime": 1545205770, "eventSource": "qcs::cos", "requestParameters": { "requestSourceIP": "192.168.15.101", "requestHeaders": { "Authorization": "q-sign-algorithm=sha1&q-ak=AKIDQm6iUh3NJ6jL41tVUis9KpY5Rgv49zyC&q-sign-time=1545205709;1545215769&q-key-time=1545205709;1545215769&q-header-list=host;x-cos-storage-class&q-url-param-list=&q-signature=098ac7dfe9cf21116f946c4b4c29001c2b449b14" } }, "eventQueue": "qcs:0:lambda:cd:appid/1253970026:default.printevent.$LATEST", "reservedInfo": "", "reqid": 179398952 } }] }
根據(jù)這個結構,我們可以確定出相關詳細信息,例如存儲桶/APPID以及圖片的Key等。將上面的代碼按照函數(shù)計算的格式進行改寫:
# -*- coding: utf8 -*- import os from PIL import Image, ImageFont, ImageDraw from qcloud_cos_v5 import CosConfig from qcloud_cos_v5 import CosS3Client secret_id = os.environ.get('secret_id') secret_key = os.environ.get('secret_key') region = os.environ.get('region') cosClient = CosS3Client(CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key)) def compressImage(image, width): height = image.size[1] / (image.size[0] / width) return image.resize((int(width), int(height))) def watermarImage(image, watermarkStr): txtImage = Image.new('RGBA', image.size, (0, 0, 0, 0)) font = ImageFont.truetype("Brimborion.TTF", 40) drawImage = ImageDraw.Draw(txtImage) height = [] width = [] for eveStr in watermarkStr: thisWidth, thisHeight = drawImage.textsize(eveStr, font) height.append(thisHeight) width.append(thisWidth) drawImage.text((txtImage.size[0] - sum(width) - 10, txtImage.size[1] - max(height) - 10), watermarkStr, font=font, fill=(255, 255, 255, 255)) return Image.alpha_composite(image, txtImage) def main_handler(event, context): for record in event['Records']: bucket = record['cos']['cosBucket']['name'] + '-' + record['cos']['cosBucket']['appid'] key = "/".join(record['cos']['cosObject']['key'].split("/")[3:]) download_path = '/tmp/{}'.format(key.split('/')[-1]) download_path = '/tmp/{}'.format(key.split('/')[-1]) upload_path = '/tmp/new_mp4-{}'.format(key.split('/')[-1]) # 下載圖片 response = cosClient.get_object(Bucket=bucket, Key=key) response['Body'].get_stream_to_file(download_path) # 圖片處理 image = Image.open(download_path) image = compressImage(image, width=500) image = watermarImage(image, "Hello Serverless") image.save(upload_path) # 上傳圖片 cosClient.put_object_from_local_file( Bucket=bucket, LocalFilePath=upload_path, Key="/compress-watermark/" + key.split('/')[-1] )
此時,新建serverless.yaml
文件:
MyPicture: component: "@serverless/tencent-scf" inputs: name: MyPicture codeUri: ./ handler: index.main_handler runtime: Python3.6 region: ap-guangzhou description: My Picture Compress And Watermark memorySize: 128 timeout: 20 environment: variables: secret_id: 用戶密鑰id secret_key: 用戶密鑰key region: ap-guangzhou events: - cos: name: picture-1256773370.cos.ap-guangzhou.myqcloud.com parameters: bucket: picture-1256773370.cos.ap-guangzhou.myqcloud.com filter: prefix: source/ events: cos:ObjectCreated:* enable: true
可以看到,這個函數(shù)有一個cos
觸發(fā)器,觸發(fā)器是針對存儲桶picture-1256773370
下面source/
目錄下的資源創(chuàng)建進行觸發(fā)。
將項目通過通過serverless
進行部署:
部署完成之后,我們在存儲桶picture-1256773370
中,新建source/
目錄與compress-watermark/
目錄。
前者用來上傳文件,后者用來生成新的文件。隨機搜索一張圖片:
可以看到這張圖片4.5M,還是蠻大的,將這個圖片上傳到source/
目錄下:
稍等片刻,可以在compress-watermark/
目錄下發(fā)現(xiàn)有一個新的文件生成:
將文件下載下來,查看詳情:
可以看到,圖片尺寸,明顯變小,并且從4.5M壓縮到了340K,與此同時圖像右下角出現(xiàn)了預設的水印標志。
至此,我們完成了通過COS觸發(fā)器實現(xiàn)的圖片壓縮與水印功能。
本實驗成功實現(xiàn)了用戶上傳圖像,通過Serverless架構對其進行壓縮與增加水印的功能。在這個功能中,我們可以看到,通過Serverless架構可以解決很多傳統(tǒng)生產(chǎn)中遇到的問題,并且可以更節(jié)約資源,節(jié)約成本對常見的問題進行新策略的定制,當我們的服務面臨高并發(fā)的時候,傳統(tǒng)情況下,很可能會由于圖像壓縮,水印的操作導致我們的服務掛掉,但是通過這樣一個策略,就算是高并發(fā)出現(xiàn),也僅僅是將圖片傳入對象存儲,至于轉換的邏輯、壓縮的邏輯以及水印的邏輯等都是有Serverless架構幫我們實現(xiàn)。對我們而言可以說是既安全穩(wěn)定,又節(jié)約成本和資源。 作為拋磚引玉的文章,僅僅以壓縮與水印為例,除此之外,還可以有圖像標準化、不同尺寸圖像制作、視頻壓縮、不同分辨率的視頻制作甚至是可以通過深度學習對圖像進行打標簽等。這些的一切都可以異步完成,交給Serverless架構完成。
上述就是小編為大家分享的Serverless如何實現(xiàn)圖片壓縮與水印了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。