如何优化Python中十六进制字符串转图像的性能?
优化图像与十六进制字符串反向转换的性能问题
我正在开发一款Python程序,实现图像与十六进制字符串的双向转换:需要两个函数,一个接收图像并返回对应每个像素RGB值的十六进制字符串;另一个接收十六进制字符串及两个整数(尺寸参数),生成对应尺寸的可视图像。
目前正向转换(图像转十六进制字符串)速度较快,处理918×575像素、442KB的图像耗时约2.5秒,但反向转换(十六进制字符串转回图像)性能极差,同尺寸图像对应的字符串耗时长达36秒。
现有代码
def rgb2hex(rgb): """ convert a list or tuple of RGB values to a string in hex """ r,g,b = rgb return '{:02x}{:02x}{:02x}'.format(r, g, b) def arrayToString(array): """ convert an array to a string """ string = "" for element in array: string += str(element) return string def sliceStr(string,sliceLenght): """ slice a string in chunks of sliceLenght lenght """ string = str(string) array = np.array([string[i:i+sliceLenght] for i in range(0,len(string),sliceLenght)]) return array def hexToRGB(hexadecimal): """ convert a hex string to an array of RGB values """ h = hexadecimal.lstrip('#') if len(h)!=6: return return [int(h[i:i+2], 16) for i in (0, 2, 4)] def ImageToBytes(image): """ Image to convert from image to bytes """ dataToEncrypt =imageio.imread(image) if dataToEncrypt.shape[2] ==4: dataToEncrypt = np.delete(dataToEncrypt,3,2) originalRows, originalColumns,_ = dataToEncrypt.shape #converting rgb to hex hexVal = np.apply_along_axis(rgb2hex, 2, dataToEncrypt) hexVal = np.apply_along_axis(arrayToString, 1, hexVal) hexVal = str(np.apply_along_axis(arrayToString, 0, hexVal)) byteImage = bytes.fromhex(hexVal) return (byteImage, [originalRows,originalColumns]) def BytesToImage(byteToConvert,originalRows,originalColumns,name): """ Convert from Bytes to Image """ Data = byteToConvert.hex() stepOne = sliceStr(Data,originalColumns*6) stepTwo = [] for i in stepOne: step = sliceStr(i,6) #Add lost pixels while len(step) != originalColumns: step = np.append(step,"ffffff") stepTwo.append(step) stepThree = [] for i in stepTwo: d = [] for j in i: d.append(hexToRGB(j)) if len(stepThree) < originalRows: stepThree.append(d) Img = np.asarray(stepThree) imageio.imwrite(name,Img)
性能瓶颈分析
反向转换慢的核心原因是大量不必要的字符串操作和嵌套循环:
- 将字节数据转回十六进制字符串后,手动切片拆分像素,Python原生循环处理数十万像素时效率极低
- 逐像素调用
hexToRGB函数,函数调用的累积开销巨大 - 频繁的列表拼接和numpy数组转换,内存操作冗余
优化方案
反向转换无需经过十六进制字符串处理,直接利用字节数据与RGB通道的对应关系,结合numpy的向量化操作一次性完成转换,彻底规避循环开销:
优化后的反向转换函数
import numpy as np import imageio def BytesToImage(byteToConvert, originalRows, originalColumns, name): # 将字节数据直接转换为uint8类型的numpy数组(每个字节对应一个RGB通道值) img_array = np.frombuffer(byteToConvert, dtype=np.uint8) # 重塑为图像的(行, 列, 3) RGB形状 img_array = img_array.reshape((originalRows, originalColumns, 3)) # 写入图像文件 imageio.imwrite(name, img_array)
附加正向转换小优化
原arrayToString函数的循环字符串拼接效率低,可替换为更高效的join方法:
def arrayToString(array): return ''.join(array)
优化效果说明
- 反向转换不再处理十六进制字符串,直接通过numpy将字节数据映射为RGB数组,耗时可降至几十毫秒级别,性能提升数百倍
- 完全利用numpy的底层优化(C实现),避免Python解释器的循环开销
内容的提问来源于stack exchange,提问作者Rararat
相关产品推荐
相关产品推荐

