如何在 Python 中使用 Alpha/Transparent 加密 PNG 文件?

How to Encrypt PNG Files with Alpha/Transparent in Python?

因此,我有以下示例 Python 代码。该代码将接受 PNG 明文输入并将其加密为 PNG 密文(加扰像素)作为输出。

但是当我尝试使用具有透明度(alpha 通道)的 PNG 时,它不起作用。如何读取4通道(rgba)存入一个Nummpy Array,加密再解密得到原图?

import cv2
import numpy as np
from Crypto.Cipher import AES

# 
key = b'Sixteen byte key'
iv = b'0000000000000000'

# Read image to NumPy array - array shape is (300, 451, 3)
img = cv2.imread('chelsea.png')

# Pad zero rows in case number of bytes is not a multiple of 16 (just an example - there are many options for padding)
if img.size % 16 > 0:
    row = img.shape[0]
    pad = 16 - (row % 16)  # Number of rows to pad (4 rows)
    img = np.pad(img, ((0, pad), (0, 0), (0, 0)))  # Pad rows at the bottom  - new shape is (304, 451, 3) - 411312 bytes.
    img[-1, -1, 0] = pad  # Store the pad value in the last element

img_bytes = img.tobytes()  # Convert NumPy array to sequence of bytes (411312 bytes)
enc_img_bytes = AES.new(key, AES.MODE_CBC, iv).encrypt(img_bytes)  # Encrypt the array of bytes.

# Convert the encrypted buffer to NumPy array and reshape to the shape of the padded image (304, 451, 3)
enc_img = np.frombuffer(enc_img_bytes, np.uint8).reshape(img.shape)

# Save the image - Save in PNG format because PNG is lossless (JPEG format is not going to work).
cv2.imwrite('enctypted_chelsea.png', enc_img)



# Decrypt:
################################################################################
key = b'Sixteen byte key'
iv = b'0000000000000000'

enc_img = cv2.imread('enctypted_chelsea.png')

dec_img_bytes = AES.new(key, AES.MODE_CBC, iv).decrypt(enc_img.tobytes())

dec_img = np.frombuffer(dec_img_bytes, np.uint8).reshape(enc_img.shape)  # The shape of the encrypted and decrypted image is the same (304, 451, 3)

pad = int(dec_img[-1, -1, 0])  # Get the stored padding value

dec_img = dec_img[0:-pad, :, :].copy()  # Remove the padding rows, new shape is (300, 451, 3)

# Show the decoded image
cv2.imshow('dec_img', dec_img)
cv2.waitKey()
cv2.destroyAllWindows()

如果要用OpenCV读取RGBA图像和16位PNG图像,需要使用:

im = cv2.imread('image.png', cv2.IMREAD_UNCHANGED)

尝试一下,然后检查 im.shape 是否为 (h,w,4)