Python 提供了豐富的函式庫,簡化了各種檔案格式的處理,包含壓縮檔、JSON 和 CSV 等常見格式。zipfile 模組能有效處理 ZIP 壓縮檔,包含讀取、建立和解壓縮檔案。json 模組則能將 Python 物件與 JSON 格式互相轉換,方便資料交換和儲存。csv 模組則能解析和生成 CSV 檔案,處理結構化表格資料。此外,文章也介紹了影像隱寫術的基礎概念,以及如何使用 Pillow 函式庫操作圖片,包含讀取、儲存、檢視元資料和解析 Exif 資訊等技巧。這些技術在資料處理、分析和影像處理等領域都有廣泛應用,能有效提升開發效率。
使用 Python 處理壓縮檔、JSON 檔案與 CSV 檔案
本章節將介紹如何使用 Python 處理三種常見的檔案格式:壓縮檔、JSON 檔案與 CSV 檔案。這些檔案格式在資料處理和分析中非常常見,瞭解如何使用 Python 操作這些檔案對於資料科學和分析工作至關重要。
處理壓縮檔
Python 的 zipfile 模組提供了方便的方法來讀取和寫入 ZIP 檔案。要開啟一個 ZIP 檔案,可以使用以下程式碼:
import zipfile
with zipfile.ZipFile("demo.zip", "r") as archive:
# 在此處理檔案
pass
內容解密:
zipfile.ZipFile("demo.zip", "r")用於開啟名為 “demo.zip” 的 ZIP 檔案,"r"表示以讀取模式開啟。- 使用
with陳述式可以確保在完成處理後,檔案能夠正確關閉。
若要建立一個新的 ZIP 檔案並使用壓縮演算法,可以使用以下程式碼:
with zipfile.ZipFile("test.zip", "w", compression=zipfile.ZIP_DEFLATED) as archive:
# 在此新增檔案到 ZIP
pass
內容解密:
"w"表示以寫入模式開啟 ZIP 檔案,如果檔案不存在則會建立它。compression=zipfile.ZIP_DEFLATED指定使用 DEFLATE 壓縮演算法來減少檔案大小。
讀取 ZIP 檔案中的成員檔案可以使用巢狀的 with 陳述式:
with archive.open("some_file") as member:
text = member.read()
print(text)
內容解密:
archive.open("some_file")用於開啟 ZIP 檔案中的 “some_file” 成員。member.read()讀取成員檔案的內容。
對於某些無法直接讀取的檔案(如圖片),需要先將其解壓縮到本地檔案系統:
with zipfile.ZipFile("photos.zip", "r") as archive:
archive.extract("warship.png")
內容解密:
archive.extract("warship.png")將名為 “warship.png” 的成員檔案解壓縮到當前目錄。
處理 JSON 檔案
JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。Python 的 json 模組提供了將 Python 物件序列化為 JSON 以及將 JSON 反序列化為 Python 物件的功能。
寫入 JSON 檔案:
import json
an_object = {"key": "value"}
with open("some_file.json", "w") as output:
json.dump(an_object, output)
內容解密:
json.dump(an_object, output)將an_object物件序列化為 JSON 並寫入到output檔案中。
讀取 JSON 檔案:
with open("some_file.json") as input:
an_object = json.load(input)
# 處理 an_object
pass
內容解密:
json.load(input)從input檔案中讀取 JSON 資料並反序列化為 Python 物件。
處理 CSV 檔案
CSV(Comma-Separated Values)是一種常見的用於儲存表格資料的純文字格式。Python 的 csv 模組提供了讀取和寫入 CSV 檔案的功能。
讀取 CSV 檔案:
import csv
import io
import urllib.request
with urllib.request.urlopen("https://example.com/data.csv") as document:
history_data = document.read().decode("utf-8")
reader = csv.reader(io.StringIO(history_data))
for row in reader:
print(row)
內容解密:
urllib.request.urlopen用於開啟 URL 連結並讀取其內容。csv.reader(io.StringIO(history_data))建立一個 CSV 讀取器物件,用於解析history_data中的 CSV 資料。for row in reader用於逐行讀取 CSV 資料。
對於使用不同分隔符號的 CSV 檔案(如使用 tab 分隔),可以透過指定 delimiter 引數來處理:
rdr = csv.reader(some_file, delimiter='\t')
內容解密:
delimiter='\t'指定使用 tab 字元作為欄位分隔符號。
影像隱寫術:使用 Pillow 函式庫進行秘密訊息編碼
影像基礎與畫素編碼
數點陣圖像由稱為畫素的影像元素組成,每個畫素是一個點。電腦顯示器上的畫素使用紅綠藍(RGB)顏色進行編碼。每個顯示的畫素是紅、綠和藍光強度的總和。對於列印,顏色可能會切換為青色-洋紅-黃色-黑色(CMYK)顏色。
影像檔案包含影像各個畫素的編碼。影像檔案也可能包含有關影像的中繼資料。中繼資料資訊有時被稱為標籤,甚至是 Exif 標籤。
影像檔案可以使用各種編碼方式來表示每個畫素。純黑白影像每個畫素只需要 1 位元。高品質的照片可能每個顏色使用 1 位元組,導致每個畫素 24 位元。在某些情況下,我們可能會新增透明度遮罩或尋求更高解析度的顏色,這會導致每個畫素 4 位元組。
儲存需求迅速成為一個問題。填充 iPhone 顯示器的圖片每英寸有 326 個畫素。顯示器的解析度為 1136 x 640 畫素。如果每個畫素使用 4 位元組的顏色資訊,那麼該影像涉及 3 MB 的記憶體。
考慮一張以 326 畫素/英寸掃描的 8.5" x 11" 影像,其大小為 2762 x 3586 畫素,總計 39 MB。有些掃描器能夠以 1200 畫素/英寸產生影像:該檔案將達到 673 MB。
不同的影像檔案反映了不同的策略來壓縮這龐大的資料量而不丟失影像品質。
影像壓縮演算法
簡單的壓縮演算法可以使檔案變小一些。例如,TIFF 檔案使用相當簡單的壓縮。然而,JPEG 使用的演算法相當複雜,可以在保留大部分原始影像的同時實作相對較小的檔案大小。雖然 JPEG 在壓縮方面非常出色,但壓縮後的影像並不完美——為了實作良好的壓縮,會丟失一些細節。這使得 JPEG 不適合隱寫術,因為我們將調整位元以隱藏影像中的訊息。
我們可以將 JPEG 壓縮稱為「有損」,因為某些位元可能會丟失。我們可以將 TIFF 壓縮稱為「無損」,因為可以還原所有原始位元。一旦位元丟失,就無法還原。由於我們的訊息只會調整幾個位元,JPEG 壓縮可能會破壞我們的隱藏訊息。
使用 Pillow 函式庫
我們將使用一些很酷的 Python 軟體來處理影像。Pillow 套件是一個成熟的影像處理函式庫。該函式庫提供了廣泛的檔案格式支援、高效的內部表示和相當強大的影像處理能力。欲瞭解更多資訊,請造訪 https://pypi.python.org/pypi/Pillow/2.1.0 。Pillow 檔案將提供重要的背景知識。PyPi 網頁上的安裝是必讀的內容,您將在這裡獲得一些額外的細節。Pillow 的核心檔案位於 http://pillow.readthedocs.org/en/latest/ 。
請注意,Pillow 將安裝一個名為 PIL 的套件。這確保了 Pillow(專案)建立了一個與 Python Imaging Library(PIL)相容的模組。我們將從 PIL 套件中匯入模組,即使我們將安裝由 Pillow 專案建立的軟體。
from PIL import Image
# 開啟一個影像檔案
img = Image.open('example.jpg')
# 將影像轉換為 RGB 模式
img = img.convert('RGB')
# 取得影像的寬度和高度
width, height = img.size
#### 內容解密:
此程式碼片段展示瞭如何使用 Pillow 函式庫開啟一個影像檔案,將其轉換為 RGB 模式,並取得其寬度和高度。首先,我們從 PIL 套件中匯入 Image 模組。然後,我們使用 `Image.open()` 方法開啟一個名為 'example.jpg' 的影像檔案。接著,我們使用 `convert()` 方法將影像轉換為 RGB 模式,這是大多數影像處理任務所需的格式。最後,我們使用 `size` 屬性取得影像的寬度和高度,並將其儲存在 `width` 和 `height` 變數中。
新增必要的支援函式庫
如果您是 Windows 使用者,可以跳過本文。Pillow 的開發者已經考慮到了 Windows 使用者的需求。對於其他人來說,您的作業系統可能尚未準備好使用 Pillow。在安裝 Pillow 之前,必須具備一些支援軟體基礎設施。一旦所有支援軟體都準備就緒,就可以安裝 Pillow 了。
GNU/Linux 系統的秘密
我們需要在 GNU/Linux 組態中具備以下函式庫。很可能這些檔案已經存在於給定的發行版中。如果這些檔案不存在,就需要進行一些升級或安裝。安裝以下內容:
- libjpeg:此函式庫提供對 JPEG 影像的存取;已測試版本 6b、8 和 9
- zlib:此函式庫提供對壓縮 PNG 影像的存取
- libtiff:此函式庫提供對 TIFF 影像的存取;已測試版本 3.x 和 4.0
- libfreetype:此函式庫提供字型相關服務
- littlecms:此函式庫提供色彩管理
- libwebp:此函式庫提供對 WebP 格式的存取
每個 Linux 發行版都有其獨特的安裝和組態函式庫的方法。我們無法涵蓋所有這些方法。
# 在 GNU/Linux 系統上安裝必要的函式庫
sudo apt-get install libjpeg-dev zlib1g-dev libtiff-dev libfreetype6-dev liblcms2-dev libwebp-dev
#### 內容解密:
此命令用於在 GNU/Linux 系統上安裝必要的函式庫,以便使用 Pillow。首先,我們使用 `apt-get` 命令,這是一個用於處理 Debian 系統上套件的工具。我們指定了需要安裝的套件,包括 libjpeg-dev、zlib1g-dev、libtiff-dev、libfreetype6-dev、liblcms2-dev 和 libwebp-dev。這些套件提供了 Pillow 所需的各種影像處理功能。
一旦支援函式庫就緒,我們就可以使用 easy_install-3.3 pillow 命令安裝 Pillow。
Mac OS X 系統的秘密
要在 Mac 上安裝 Pillow,需要執行三個初步步驟。我們需要 Xcode 和 Homebrew,然後使用 Homebrew。
首先,從 https://developer.apple.com/xcode/downloads/ 下載 Xcode。每個 Mac OS X 使用者都應該擁有 Xcode,即使他們不打算編寫原生的 Mac OS X 或 iOS 應用程式。
安裝 Xcode 時,請務必同時安裝命令列開發工具。這是另一個龐大的下載,超出了基本的 Xcode 下載。
安裝 Xcode 命令列工具後,第二個初步步驟是從 http://brew.sh 安裝 Homebrew。此應用程式為 Mac OS X 建立和安裝 GNU/Linux 二進位檔案。Homebrew 與 Python 無直接關係;這是一個流行的 Mac OS X 開發工具。
Homebrew 的安裝是一行命令,在終端機視窗中輸入:
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
#### 內容解密:
此命令用於在 Mac OS X 系統上安裝 Homebrew。首先,它使用 `curl` 命令下載 Homebrew 安裝套件,然後使用 Ruby 執行該安裝程式,以建立各種 Homebrew 工具和指令碼。
第三步是使用 brew 程式安裝 Pillow 所需的其他函式庫。以下命令列將處理這項任務:
brew install libtiff libjpeg webp littlecms
#### 內容解密:
此命令用於在 Mac OS X 系統上使用 Homebrew 安裝必要的函式庫,以便使用 Pillow。它指定了需要安裝的套件,包括 libtiff、libjpeg、webp 和 littlecms。
完成三個初步步驟後,我們就可以使用 easy_install-3.3 pillow 命令安裝 Pillow 了。
Windows 環境下的 Pillow 安裝與設定
在 Windows 環境下安裝 Pillow 時,預先建置的函式庫已經包含在安裝套件中。這些函式庫包括:
- libjpeg
- zlib
- libtiff
- libfreetype
- littlecms
- libwebp
安裝完成後,這些模組將可供 Pillow 使用。
安裝與確認 Pillow
在安裝 Pillow 之前,請確保所有必要的支援工具已經就緒。安裝 Pillow 的指令如下:
sudo easy_install-3.3 pillow
在 Windows 環境下,請省略 sudo 指令。
安裝結果範例
安裝結果的部分輸出如下:
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
PIL SETUP SUMMARY
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
version Pillow 2.4.0
platform darwin 3.3.4 (v3.3.4:7ff62415e426, Feb 9 2014, 00:29:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
TKINTER support available
---
JPEG support available
*** OPENJPEG (JPEG2000) support not available
---
ZLIB (PNG/ZIP) support available
---
LIBTIFF support available
*** FREETYPE2 support not available
*** LITTLECMS2 support not available
---
WEBP support available
---
WEBPMUX support available
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
---
-
內容解密:
- 上述輸出顯示了 Pillow 的安裝結果,包括版本資訊和各項支援函式庫的可用性。
- `
表示支援可用,而***` 表示支援不可用。
- 若某些支援不可用,可透過安裝對應的函式庫並調整
setup.py中的ROOT變數來解決。
測試 Pillow 安裝
可使用 Pillow 內建的測試指令碼進行測試:
>>> from PIL import Image
>>> pix = Image.open("1drachmi_1973.jpg")
>>> pix
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=198x194 at 0x10183BA90>
>>> pix.save("test.tiff")
內容解密:
- 上述程式碼測試了 Pillow 的基本功能,包括開啟圖片檔案和轉存為不同格式。
Image.open()用於開啟圖片檔案,而save()方法則用於將圖片儲存為其他格式。
解碼與編碼圖片資料
圖片檔案以特定格式編碼,以便於讀寫,但不利於詳細處理。Pillow 簡化了圖片檔案的解碼和編碼過程。
基本圖片處理流程
from PIL import Image
pix = Image.open("LHD_warship.jpg")
內容解密:
- 上述程式碼開啟了一個圖片檔案,並將其載入到
pix物件中。 - Pillow 從圖片的元資料中擷取了多項屬性。
檢檢視片元資料
>>> pix.info.keys()
dict_keys(['jfif_density', 'icc_profile', 'jfif_version', 'jfif', 'exif', 'jfif_unit', 'dpi'])
>>> exif = pix._getexif()
>>> exif.keys()
dict_keys([36864, 37121, 37378, 36867, 36868, 41989, 40960, 37383, 37385, 37386, 40962, 271, 272, 37521, 37522, 40963, 37396, 41495, 41988, 282, 283, 33434, 37500, 34850, 40961, 34853, 41986, 34855, 296, 34665, 41987, 41990, 42034, 33437, 305, 306, 42035, 42036, 41729])
內容解密:
- 上述程式碼檢視了圖片的元資料,包括 Exif 資訊。
- Exif 資訊需要使用
_getexif()方法來解碼。 - 解碼後的 Exif 資訊包含多項標籤和對應的值。
解析 Exif 資訊
>>> import PIL.ExifTags
>>> for k, v in pix._getexif().items():
... print(PIL.ExifTags.TAGS[k], v)
內容解密:
- 上述程式碼解析了 Exif 資訊中的標籤和對應的值。
- 使用
PIL.ExifTags.TAGS將數值標籤轉換為有意義的字串。
輸出範例
輸出結果可能如下:
Software 7.1.1
DateTime 2014:05:10 09:59:22
LensMake Apple
LensModel iPhone 4 back camera 3.85mm f/2.8
內容解密:
- 上述輸出顯示了圖片的 Exif 資訊,包括拍攝裝置、時間等資訊。