2022/05/20(金) [n年前の日記]
#2 [python][gimp] Python 3 でARGBからRGBAに変換
Windows10 x64 21H2 + Python 3.9.12 64bit の環境で、ARGB(BRGA)からRGBAに変換する処理を試してみた。
ちなみに、Python 2.7.18 を使って処理する版は、 _昨日 試した。
とりあえず、Python 3.9.12 で動く処理だけ抜き出してベンチマークを取ってみた。
_05_argb_rgba_conv_py3.py
ベンチマーク結果は以下。
やはり、bytearray を使って入れ替えていく書き方は、struct.pack や unpack、リスト内包表記を使う書き方と比べると、ちょっと遅い模様。
また、Python 2.7 より 3.9 で処理するほうが、処理時間が短くなる場合もあるらしい。Python 2.7 では 1秒台だった処理が、Python 3.9 では 0.84秒になった。
ちなみに、Python 2.7.18 を使って処理する版は、 _昨日 試した。
とりあえず、Python 3.9.12 で動く処理だけ抜き出してベンチマークを取ってみた。
_05_argb_rgba_conv_py3.py
from benchmarker import Benchmarker
import struct
import sys
# check_data_enable = True
check_data_enable = False
LOOP = 5
if sys.version_info.major != 3:
print("This script is compatible only with Python3.")
sys.exit()
def create_src_data():
print("start.")
r, g, b, a = 0, 1, 2, 3
w, h = 2048, 2048
rgba = bytearray(w * h * 4)
for i in range(0, len(rgba), 4):
rgba[i], rgba[i + 1], rgba[i + 2], rgba[i + 3] = b, g, r, a
src = rgba
print("create source data. %d byte" % len(src))
# for i in range(8):
# print(src[i])
return src
def get_rgba_str_g(src):
lmax = len(src) // 4
argb = list(struct.unpack("=%dL" % lmax, src))
rgba = [(((d & 0x0ffffff) << 8) + ((d >> 24) & 0x0ff)) for d in argb]
return struct.pack(">%dL" % lmax, *rgba)
def get_rgba_str_j(src):
cnt = len(src)
dst = bytearray(cnt)
if sys.byteorder == "little":
for i in range(0, cnt, 4):
dst[i], dst[i + 1], dst[i + 2], dst[i + 3] = src[i + 2], src[i + 1], src[i], src[i + 3]
else:
for i in range(0, cnt, 4):
dst[i], dst[i + 1], dst[i + 2], dst[i + 3] = src[i + 1], src[i + 2], src[i + 3], src[i]
return dst
def check_result(src):
print("compare")
dst = []
dst.append(get_rgba_str_g(src))
dst.append(get_rgba_str_j(src))
for i in range(1, len(dst)):
if dst[0] == dst[i]:
print("Success [%d]" % i)
else:
print("Failure [%d]" % i)
src = create_src_data()
if check_data_enable:
# compare result data
check_result(src)
sys.exit()
with Benchmarker(LOOP, width=20) as bench:
@bench("rgb shift G")
def check_use_rgb_shift_g(bm):
get_rgba_str_g(src)
@bench("rgb shift J")
def check_use_rgb_shift_j(bm):
get_rgba_str_j(src)
ベンチマーク結果は以下。
> py -3 05_argb_rgba_conv_py3.py start. create source data. 16777216 byte ## benchmarker: release 4.0.1 (for python) ## python version: 3.9.12 ## python compiler: MSC v.1929 64 bit (AMD64) ## python platform: Windows-10-10.0.19044-SP0 ## python executable: C:\Python\Python39-64\python.exe ## cpu model: AMD64 Family 23 Model 113 Stepping 0, AuthenticAMD ## parameters: loop=5, cycle=1, extra=0 ## real (total = user + sys) rgb shift G 0.8407 0.8438 0.7344 0.1094 rgb shift J 1.4964 1.5000 1.4844 0.0156 ## Ranking real rgb shift G 0.8407 (100.0) ******************** rgb shift J 1.4964 ( 56.2) *********** ## Matrix real [01] [02] [01] rgb shift G 0.8407 100.0 178.0 [02] rgb shift J 1.4964 56.2 100.0
やはり、bytearray を使って入れ替えていく書き方は、struct.pack や unpack、リスト内包表記を使う書き方と比べると、ちょっと遅い模様。
また、Python 2.7 より 3.9 で処理するほうが、処理時間が短くなる場合もあるらしい。Python 2.7 では 1秒台だった処理が、Python 3.9 では 0.84秒になった。
[ ツッコむ ]
以上です。