0

Всем добра.

Приходит строка байт buffered_img длиной 786’432 байта (Grayscale 8bit изображение 1024x768). Запускается обработчик в отдельном потоке (если считать в основном потоке, то просто виснет окно). Алгоритм такой: берется 0-вой пиксель из оригинального изображения (первый байт из строки buffered_img), проверяется его 7-ой бит, если он равен 0, то к строке nine['img_7'] дописывается байт '\x00', если 1, то '\xff', затем берется 6-ой бит 0-го пикселя, также проверяется и дописывается к nine['img_6'] и т.д. до 0 бита. Эта операция повторяется для всех пикселей. В итоге получаем 9 изображений: оригинальное + 8 генерированных.

Так вот, проблема в том, что с каждой операцией конкатенации, процесс замедляется, ползунок QProgressBar (PyQt5), который завязан на сигнал generating, ползет все медленнее и медленнее с каждым процентом, хотя поначалу все идет бодро. Если бы проценты капали с самого начала медленно, претензий бы не возникло, но на лицо явное замедление процесса конкатенации, и моего скудного опыта в программировании не хватает, для того, чтобы объяснить это явление. Кто подскажет, в чем проблема? Вот кусочки кода:

# Глобальный словарь с байт-строками генерированных картинок
nine = {'img_7': b'', 'img_6': b'', 'img_5': b'', 'img_4': b'',
    'img_3': b'', 'img_2': b'', 'img_1': b'', 'img_0': b''}
b0 = pack('B', 0)
b255 = pack('B', 255)
 
# Метод run() QThread в котором buffered_img - байт строка с оригинальным изображением
def run(self):
    global nine, img_str
    self.start_gen.emit(len(buffered_img))
    pb_val = 0
    for img in nine:
        nine[img] = b''
    for byte_ in buffered_img:
        pb_val += 1
        self.generating.emit(pb_val)
        bit_str = self.by2bi(byte_)
        for i in range(8):
            if bit_str[i] == '0':
                nine['img_' + str(i)] += b0
            else:
                nine['img_' + str(i)] += b255
    self.stop_gen.emit()
 
# Подсмотренный где-то код, на выходе выдает строку типа ('10110100' для
# входного байта '\xb4'
def by2bi(self, bytestring):
    try:
        bits = bin(int(hexlify(bytestring), 16))[2:]
        data = bits.zfill(8 * ((len(bits) + 7) // 8))
        del bits
        return data
    except ValueError:
        print 'Error bytes2bits decode!'


Добавить комментарий