Python 旋轉圖片 rotate

本篇 ShengYu 將介紹如何使用 Python 來旋轉圖片,在做影像處理時常常會需要用旋轉圖片的功能,這邊我們使用 python 的 PIL 模組來作圖片的旋轉。

安裝 PIL

基本上新版本的 Python 應該都有內建 PIL,如果還未安裝 PIL 的話請參考這篇

使用範例

以下範例是 ShengYu 將 lena.jpg 這張圖片從原本的角度透過 rotate() 函式來順時針旋轉45度,最後顯示並且存檔。

rotate-image.py
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PIL import Image

img = Image.open("lena.jpg")
img.show()

new_img = img.rotate(45)
new_img.show()
new_img.save("lena-rotate45.jpg")

結果如下圖所示:
左邊為原圖,右邊為旋轉後的圖。

Image.rotate 參數的詳細細節請參考這裡

相關主題
Python 水平翻轉、垂直翻轉圖片
Python 圖片模糊化 blur
Python 縮放圖片 resize
Python 裁切裁剪圖片 crop
Python 在圖片上繪製文字

Python 縮放圖片 resize

本篇 ShengYu 將介紹如何使用 Python 來縮放圖片,在做影像處理時常常會需要用縮放圖片的功能,這邊我們使用 python 的 PIL 模組來作圖片的縮放。

安裝 PIL

基本上新版本的 Python 應該都有內建 PIL,如果還未安裝 PIL 的話請參考這篇

使用範例

以下範例 ShengYu 是將 lena.jpg 這張圖片從原本的 512x512 大小縮放成 256x256 大小,之後顯示並且存檔。

resize-image.py
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PIL import Image

img = Image.open("lena.jpg")
(w, h) = img.size
print('w=%d, h=%d', w, h)
img.show()

new_img = img.resize((256, 256))
new_img.show()
new_img.save("lena-256x256.jpg")

結果如下圖所示:
左邊為原圖,右邊為縮放後的圖。

另外如果只是想將圖片等比例縮小的話可以參考 PIL 提供的另外一個函式,製作圖片縮圖的 thumbnail()

其他參數說明

Image.resize 第一個參數為 size:(width, height)
第二個參數為 resample:

resample 參數 說明
PIL.Image.NEAREST 最鄰近插值 (預設?)
PIL.Image.BOX
PIL.Image.BILINEAR
PIL.Image.HAMMING
PIL.Image.BICUBIC
PIL.Image.LANCZOS

Image.resize 參數的詳細細節請參考這裡

其它相關文章推薦
如果你想學習 Python 相關技術,可以參考看看下面的文章,
Python 新手入門教學懶人包
Python 圖片模糊化 blur
Python 旋轉圖片 rotate
Python 製作圖片縮圖 thumbnail
Python 裁切裁剪圖片 crop
Python 在圖片上繪製文字

BusyBox 基本用法教學

本篇教學介紹如何使用 BusyBox,BusyBox 是一個自由軟體,它在一個可執行檔中提供了很多常用且精簡的 Unix 工具,由於 BusyBox 執行檔的檔案大小比較小,使得它非常適合使用於嵌入式系統 Embedded Linux,BusyBox 就像「嵌入式 Linux 的瑞士小刀」一樣。

使用範例

最簡單的使用指令如下,第一個參數帶入想要執行的 linux 指令

1
$ /bin/busybox ls

如果有安裝好的話應該會產生每個指令的軟連結到 busybox,
以 ls 為例,/bin/ls 軟連結到 /bin/busybox 後即可執行

1
$ /bin/ls

常見的指令

實際的命令列表按編譯時的設定決定,在有 Busybox 的系統上執行 busybox --list 即可看到一個列表。
vi: 一個帶有簡單的模式提示的精簡版仿 vi 編輯器
ls: 列出目錄或檔案
cp: 複製檔案或目錄
mv: 移動檔案或目錄
touch: 建立檔案
chmod: 更改檔案或目錄的權限
cat: 將檔案顯示於標準輸出
find: 尋找檔案或資料夾
grep: 列出檔案或標準輸入中符合模式的行
egrep: 接受擴展正則表達式的 grep
awk: 將檔案解析為記錄及字段後,按模式匹配操作其內容
sync: 將系統緩衝區寫入到硬碟裡
tee: 同時螢幕標準輸出和輸出導到檔案
sed: 取代
ps: 印出程式狀態
df: 印出檔案系統的使用統計
kill: 關閉一個程序
dmesg: 查看 kernel 訊息
date: 印出/設定日期時間
ping: 網路診斷工具
wget: HTTP 或 FTP下载工具
tar: 打包
gzip: 壓縮/解壓縮
zcat 壓縮/解壓縮
sh: shell
ash: shell

更多支援指令請參考 https://busybox.net/screenshot.html

如果你想在 Android 安裝 busybox 使用 vi 指令的話可以看這篇

Android adb 基本用法教學

本篇教學介紹如何在 Android 下使用 adb 指令,adb(Android Debug Bridge)指令是開發 Android 時常用到的工具,使用 adb 指令可對 android 裝置進行除錯、測試、檔案處理、安裝/移除 apk 等的操作,以下內容為如何安裝 Android adb 與 adb 基本使用教學。

Google 官方的 SDK Platform Tools release notes 有各版本的釋出說明。

Windows 安裝方式

從官方下載 Windows 最新版
目前最新版為 platform-tools_r34.0.5-windows.zip

Mac 安裝方式

從官方下載 Mac 最新版
目前最新版為 platform-tools_r34.0.5-darwin.zip

透過 brew 安裝

1
$ brew install android-platform-tools

Ubuntu 安裝方式

從官方下載 Linux 最新版
目前最新版為 platform-tools_r34.0.5-linux.zip

透過 apt 安裝

1
2
$ sudo apt update
$ sudo apt install android-tools-adb

adb 指令基本教學

安裝好 adb 後將 Android 裝置插上電腦的 USB 孔,在輸入下列指令,

1
2
3
$ adb devices
List of devices attached
XX00X0000000 device

如果沒有看到任何裝置就需要去 Android 裝置裡,把 USB 偵錯功能開啟,可參考這篇

先簡單地先列出有什麼目錄,輸入下列指令

1
$ adb shell ls

接著就來進入 android 的 shell 模式輸入指令吧。

1
$ adb shell

adb 常用指令選項

以下為常用的 adb 指令,有想到在陸續增加吧!
adb devices: 列出目前連線裝置清單
adb version: 印出版本號
adb shell: 進入裝置裡的 shell 模式
adb shell <指令>: 讓 adb shell 去下你想要下的指令,例如 adb shell ls 會列出目錄
adb tcpip <port>: 開啟
adb connect <ip:port>: 連上 ip:port
adb disconnect: 斷開所有 tcp 連線
adb kill-server: 終止 adb daemon
adb start-server: 啟動 adb daemon
adb wait-device: 等待裝置連線,裝置連線上才會跳出,否則一直等待
adb -s <裝置名稱> <指令>: 必須指定某台裝置名稱做某指令,例如 adb -s 192.168.1.2:5555 shell
adb install <apk>: 安裝 apk,當已經安裝過舊版本的程式時,可以使用 -r 去覆蓋。
adb pull <檔案或目錄> [<放到哪個路徑>]: 拉檔案或目錄出來
adb push <檔案或目錄> <推到哪個路徑>: 推檔案或目錄進去
adb root: 取得 root 權限
adb remount: 有 root 權限後,可用此指令將系統重新掛載成 R/W 模式,將可對 /system 內的檔案做修改
adb reboot: 重開機
adb reboot recovery: 重新機,進 入recovery 模式
adb reboot fastboot: 重新機,進入 fastboot 模式
adb reboot bootloader: 重新機,進入 bootloader 模式
adb logcat: 印出系統log日誌訊息

參考
[1] Android adb tool 功能整理
[2] adb、fastboot在那裡?下載即用的Android SDK Platform Tools / Where is adb? Android SDK Platform Tools Location and Usage
[3] mzlogin/awesome-adb

其他技巧推薦

如果你是常常在Android adb shell下做事情的話,尤其是需要使用到vi,建議安裝busybox,使用busybox附帶的vi會方便很多,
如果還想知道busybox支援哪些指令或busybox基本用法的話請看這篇
其他的 Android 系列文章可以看這篇
下一篇來介紹Android fastboot指令的安裝與用法教學吧~

其它相關推薦文章
Android adb forward 通訊埠轉發用法教學
開源專案scrcpy:讓Android投影/鏡射到電腦,還可鍵盤滑鼠操控

addr2line 用法

本篇介紹 addr2line 的用法,以及如何使用 addr2line 搭配 core dump 的記憶體位置來找程式是壞在那一行程式碼。

addr2line 指令用法

假設 xxx 可以是執行檔或 so 檔, 在 core dump 找到掛掉的 addr 資訊,接著使用 addr2line 查詢的該 addr 記憶體位置的程式碼行數跟其他資訊,指令如下,

1
$ addr2line -Cfie <xxx/xxx.so> <addr>

輸入完上列指令後, 會輸出該程式是在哪個函式掛掉的跟第幾行,如下所示,是掛在 myprint 函式裡,確切位置在 cpp-crash.cpp 的第 6 行,

1
2
myprint(int*)
/home/xxx/cpp-crash.cpp:6

addr2line 指令選項

-C: 加上這個選項可以印出 c++ namespace,而不是一堆亂碼
-f: 顯示函式名字跟檔案路徑與行數
-i:
-e: 指定檔名,預設為 a.out
--exe: 同 -e

詳細用法請參考:https://linux.die.net/man/1/addr2line

addr2line 實際練習

想要實際練習可以參考這篇來實際練習看看。

其他參考
http://lazybing.github.io/blog/2016/12/22/addr2line-use/
https://stackoverflow.com/questions/7648642/how-to-use-the-addr2line-command-in-linux
https://blog.csdn.net/olidrop/article/details/7295908

其它相關文章推薦
Linux 常用指令教學懶人包
readelf 用法與範例
nm 用法與範例
Linux ldd 查看執行檔執行時需要哪些 library

Hexo hexo-client 桌面端程式安裝教學

本篇介紹如何安裝 hexo-client,hexo-client 是 Hexo 桌面端程式,支援 Windows、Mac、Ubuntu 多平台,使用 hexo-client 的好處是讓你寫文章時更加地方便, 例如根據標籤列出文章。

接下來介紹如何安裝 hexo-client 桌面端程式吧。

如何安裝

安裝檔下載:https://github.com/gaoyoubo/hexo-client/releases
我的作業系統是 Ubuntu 64-bit,就下載 hexo-client_1.3.3_amd64.deb
下載完後,輸入下列指令進行安裝

1
$ sudo dpkg -i hexo-client_1.3.3_amd64.deb

檢查目前安裝的版本

輸入下列指令查看現在安裝的版本

1
2
$ dpkg -l | grep hexo
ii hexo-client 1.3.3-99 amd64

開始使用 hexo-client

接下來應用程式搜尋列搜尋 HexoClient 來開啟或從命令列輸入 hexo-client 來開啟 hexo-client 了。

Github 專案:https://github.com/gaoyoubo/hexo-client

相關主題
hexo-client 升級

Hexo hexo-client 升級

本篇介紹如何從舊版的 hexo-client 升級到 hexo-client 最新版,以及如何查詢目前 hexo-client 安裝的版本。

檢查目前安裝的版本

透過 dpkg 去查詢 hexo-client 版本號碼, 我目前安裝的是 hexo-client 1.2.6

1
2
$ dpkg -l | grep hexo
ii hexoclient 1.2.6-60 amd64

升級 hexo-client

我已經安裝 hexo-client 1.2.6 的版本了, 所以我先移除舊版, 再安裝新版

1
2
$ sudo apt purge hexoclient
$ sudo dpkg -i hexo-client_1.3.3_amd64.deb

檢查安裝後的版本

再次透過 dpkg 去查詢 hexo-client 版本號碼, 發現套件名稱從 hexoclient 改成 hexo-client 了,
而且版本也是目前安裝的版號,看起來已經安裝完成。

1
2
$ dpkg -l | grep hexo
ii hexo-client 1.3.3-99 amd64

開始使用 hexo-client

接下來應用程式搜尋列搜尋 HexoClient 來開啟或從命令列輸入 hexo-client 來開啟 hexo-client 了。

相關主題
Hexo hexo-client 桌面端程式安裝教學

Python 使用 datetime 日期相減

本篇要來介紹如何使用 python 的 datetime 模組作日期時間相減,並且印出相差的天數。

使用範例

以下範例為取得今天的日期,設定要相減的日期時間,最後日期時間相減後印出來。

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import datetime

today = datetime.date.today()
print('今天日期: ' + str(today))

begin_day = datetime.date(2019, 10, 17)
result = today - begin_day
print(result)
print('相差天數: ' + str(result.days))

輸出:

1
2
3
今天日期: 2019-10-19
2 days, 0:00:00
相差天數: 2

其它相關文章推薦
如果你想學習 Python 相關技術,可以參考看看下面的文章,
Python 計算程式執行時間
Python 新手入門教學懶人包
Python str 字串用法與範例
Python list 串列用法與範例
Python set 集合用法與範例
Python dict 字典用法與範例
Python tuple 元組用法與範例
Python 字串分割 split
Python 取代字元或取代字串 replace
Python 讓程式 sleep 延遲暫停時間

Python 使用 monotonic 計算程式執行時間

本篇要介紹 python 如何使用 time.monotonic() 來測量準確的程式執行時間,monotonic 是一個單調時鐘,它回傳一個不會倒退的時間,是不會受到系統時間同步更新影響。

time.time() 是查看系統時鐘,因為使用者或系統服務可以更改系統時鐘,以至於在多台電腦之間同步時鐘,所以重複呼叫 time.time() 可能會生成前後轉換的數值。

例如,現在取得開始時間,之後取得結束時間時,剛好在這段期間電腦時鐘與網路時鐘同步,就會產生量測時間的不準確情形。

當使用 time.time() 測量持續時間進行計算時,可能導致量測不準確情形,這時可以使用 time.monotonic() 來避免這些情況,因為 time.monotonic() 它總是回傳前進的值。我自己是把它理解成開機時間到現在的時間。

使用範例

以下的範例簡單示範取得開始時間t1,之後取得結束時間t2,之後兩個時間相減再印出來。

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time

t1 = time.monotonic()
time.sleep(0.1)
t2 = time.monotonic()
print('time elapsed: ' + str(round(t2-t1, 2)) + ' seconds')
print('time elapsed: ' + str(t2-t1) + ' seconds')

輸出:

1
2
time elapsed: 0.1 seconds
time elapsed: 0.10013350704684854 seconds

說明

Python 的 time.monotonic() 回傳的數值是浮點數,時間單位是秒。
另外還可以使用 time.monotonic_ns(),它回傳的是 nanoseconds 奈秒的 int 整數。
詳細可以參考 https://docs.python.org/3/library/time.html#time.monotonic

其它相關文章推薦
如果你想學習 Python 相關技術,可以參考看看下面的文章,
Python 新手入門教學懶人包
Python 讓程式 sleep 延遲暫停時間
Python str 字串用法與範例
Python list 串列用法與範例
Python set 集合用法與範例
Python dict 字典用法與範例
Python tuple 元組用法與範例
Python 字串分割 split
Python 取代字元或取代字串 replace

Python 讀取 csv 檔案

本篇介紹如何用 python read csv 檔案,csv 檔案格式是常用格式,以下將示範如何用 python 的內建 csv 模組來讀取 csv 檔案。

以下是 Python 讀取 csv 的幾個章節,分為這幾部份,

  • 相似於C語言的寫法
  • 使用 with open(…) as …
  • 取出第一欄欄位名稱 headers
  • 將讀取的欄位轉換變數類型存到串列 list 裡
  • 將讀取的 csv 內容轉成 NumPy array
  • 使用 NumPy 的 genfromtxt 來讀取 csv

相似於C語言的寫法

以下範例是將 data.csv 檔案讀取近來後, 之後將每行的內容印出來。

python3-csv-read.py
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv

path = 'data.csv'
try:
f = open(path, 'r')
rows = csv.reader(f, delimiter=',')
for row in rows:
print(row)
except:
print('ERROR: can not found ' + path)
exit(1)

data.csv 內容如下,

data.csv
1
2
3
4
1,Tom,0.2,
2,Mary,0.5,
3,Mark,0.8,
4,Jason,1.1,

輸出如下,值得注意的是行尾有一個逗號會被當成空資料,

1
2
3
4
['1', 'Tom', '87.3', '']
['2', 'Mary', '76.4', '']
['3', 'Mark', '65.5', '']
['4', 'Jason', '54.6', '']

使用 with open(…) as …

這是 Python 建議的另外一種讀取 csv 寫法,使用 with 語法,
先使用 open 再使用 csv.reader,輸出結果是一樣的。

python3-csv-read2.py
1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv

path = 'data.csv'
with open(path, newline='') as csvfile:
rows = csv.reader(csvfile, delimiter=',')
for row in rows:
print(row)

取出第一欄欄位名稱 headers

data2.csv 內容如下,

data2.csv
1
2
3
4
5
No,Name,Score
1,Tom,87.3
2,Mary,76.4
3,Mark,65.5
4,Jason,54.6

這裡next是將讀取指針移到下一行,回傳的資料為當前行數的資料,
header為csv的第一行欄位名稱

python3-csv-read3.py
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv

path = 'data2.csv'
with open(path, newline='') as csvfile:
rows = csv.reader(csvfile, delimiter=',')
headers = next(rows)
print('headers: %s' % headers)
for row in rows:
print(row)

輸出如下,值得注意的是行尾沒有逗號就沒有空資料,

1
2
3
4
5
headers: ['No', 'Name', 'Score']
['1', 'Tom', '87.3']
['2', 'Mary', '76.4']
['3', 'Mark', '65.5']
['4', 'Jason', '54.6']

將讀取的欄位轉換變數類型存到串列 list 裡

這邊示範將讀出來的每個欄位轉換成適當的變數類型,例如轉整數用 int()、轉浮點數用 float(),最後 append 到串列 list 裡,以便後續處理,

python3-csv-read4.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv

id = []
name = []
score = []
path = 'data2.csv'
with open(path, newline='') as csvfile:
rows = csv.reader(csvfile, delimiter=',')
headers = next(rows)
for row in rows:
id.append(int(row[0]))
name.append(row[1])
score.append(float(row[2]))

print(id)
print(name)
print(score)

輸出如下,

1
2
3
[1, 2, 3, 4]
['Tom', 'Mary', 'Mark', 'Jason']
[87.3, 76.4, 65.5, 54.6]

將讀取的 csv 內容轉成 NumPy array

以下範例是將讀取到 csv 內容轉成 NumPy array,

python3-csv-read5.py
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv
import numpy as np

path = 'data.csv'
with open(path, newline='') as csvfile:
rows = csv.reader(csvfile, delimiter=',')
data = np.asarray(list(rows))
print(data)

輸出:

1
2
3
4
[['1' 'Tom' '87.3' '']
['2' 'Mary' '76.4' '']
['3' 'Mark' '65.5' '']
['4' 'Jason' '54.6' '']]

使用 NumPy 的 genfromtxt 來讀取 csv

以下範例是使用 NumPy 的 genfromtxt 來讀取 csv

python3-csv-read6.py
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv
import numpy as np

path = 'data.csv'
data = np.genfromtxt(path, delimiter=',')
print(data)
print(data[0])
print(data[1])
print(data[0][0])
print(data[1][0])

輸出如下所示,字串的部份變成nan之後有空再看看為什麼,

1
2
3
4
5
6
7
8
[[ 1.   nan 87.3  nan]
[ 2. nan 76.4 nan]
[ 3. nan 65.5 nan]
[ 4. nan 54.6 nan]]
[ 1. nan 87.3 nan]
[ 2. nan 76.4 nan]
1.0
2.0

根據這篇網友提到使用 NumPy 提供的讀取csv方法來讀取會比內建csv所花飛的時間多,所以這邊是建議可以使用內建csv提供的方法。

以上就是 Python 讀取 csv 檔案的介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
csv — CSV File Reading and Writing — Python 3 documentation
https://docs.python.org/3/library/csv.html#csv.reader
Working with csv files in Python - GeeksforGeeks
https://www.geeksforgeeks.org/working-csv-files-python/

相關主題
Python 寫入 csv 檔案
Python 讀檔,讀取 txt 文字檔
Python 讀寫檔案
Python 使用 numpy 讀取 csv 資料再畫圖