과제에 대해 실행 길이 이미지 인코더를 쓰고 있습니다. 내 코드는 매우 잘 이진 및 8 비트 이미지를 작동하지만 4 비트 이미지를 인코딩 할 때 제대로 작동하지 않습니다. 나는 우분투 13.10, 파이썬 3.3.4 및 베개를 사용하고 있습니다. 다음 코드를 실행하면 True
과 True
이 인쇄되지만 True
과 False
이 인쇄됩니다.이미지의 길이 인코딩 실행
내 코드를 테스트하기 위해 랜덤 목록을 생성하여 이미지를 시뮬레이트합니다. 그것은 작동, 첫 번째 가치는 그것을 선물하지만,이 image가 작동하지 않습니다. 이런 이미지가 4 개 더 있지만 그 중 아무 것도 작동하지 않습니다. 나는 어떤 점을 놓치고 있는가? 완전한 참조 4 판 26 페이지
가 다시 한 번 비트는 각 바이트에 전념 알고리즘 데이터 압축에서
바이트 은 그레이 값 또는 수를 포함하는지 여부를 표시한다. 이번에는, 그러나, 이들 여분 비트 (8)의 그룹이 축적되고, 각 그룹은 8 바이트 위 (또는 아래)에 출력 스트림에 기록되는 " 에 대응한다."from PIL import Image import random def _encodeImage4bit(imagePixels, width, height): encodedImage = bytearray() count = 0 prev = imagePixels[0] tempmap = "" for pixel in imagePixels: if count >= 15: encodedImage.append(15) encodedImage.append(pixel) tempmap += "1" tempmap += "0" count = 0 if pixel == prev: count += 1 else: if count > 1: encodedImage.append(count) tempmap += "1" encodedImage.append(prev) tempmap += "0" count = 1 prev = pixel if count > 1: encodedImage.append(count) tempmap += "1" encodedImage.append(prev) tempmap += "0" encodedImage.extend([0] * _remaining(len(encodedImage))) tempmap += "1"*_remaining(len(tempmap)) encodedImage = _set4bitMap(tempmap, encodedImage) return encodedImage def _set4bitMap(imgMap, encodedImage): newImgMap = _divideByRow(imgMap, 8) tempImg = [_merge4bitTo8bit(encodedImage[i], encodedImage[i + 1]) for i in range(0, len(encodedImage), 2)] tempImg = _divideByRow(list(tempImg), 4) return bytearray(_flattenListOfList(_mergeMap(tempImg, newImgMap))) def _decodeImage4bit(encodedImage, width, height): decodedImage = [] imgMap, encImg = _get4bitMap(encodedImage) for index, i in enumerate(imgMap): if i == '1' and encImg[index] == 0: break if i == '1': decodedImage.extend([encImg[index + 1]] * encImg[index]) elif imgMap[index - 1] != '1' or index == 0: decodedImage.append(encImg[index]) return decodedImage def _get4bitMap(encodedImage): imgMap = "" newEncodedImage = list(encodedImage) I = range(0, len(newEncodedImage), 5) for i in I: imgMap += '{0:08b}'.format(newEncodedImage[i]) for i in sorted(list(I), reverse = True): del newEncodedImage[i] newEncodedImage = _flattenListOfList([_split8bitTo4bit(i) for i in newEncodedImage]) return (imgMap, newEncodedImage) def _split8bitTo4bit(eightbit): leftmask = 240 rightmask = 15 left = (eightbit & leftmask) >> 4 right = eightbit & rightmask return (left, right) def _merge4bitTo8bit(left, right): return (left << 4) | right _remaining = lambda x, y = 8: 0 if x % y == 0 else y - (x % y) _mergeMap = lambda z, x:[[int(x[index], 2)] + i for index, i in enumerate(z)] _flattenListOfList = lambda flat:[item for sublist in flat for item in sublist] _divideByRow = lambda flat, size: [flat[i:i + size] for i in range(0, len(flat), size)] if __name__ == "__main__": img = [15] * 100 img.extend([random.randrange(0, 16) for n in range(300)]) encImg = _encodeImage4bit(img, 20, 20) decImg = _decodeImage4bit(encImg, 20, 20) print(str(decImg == img)) imgpath = "../../images/4bit/baboon_4bit.bmp" img2 = Image.open(imgpath) encImg2 = _encodeImage4bit(list(img2.getdata(0)), img2.size[0], img2.size[1]) decImg2 = _decodeImage4bit(encImg2, img2.size[0], img2.size[1]) print(str(decImg2 == list(img2.getdata(0))))
그것을 변경 4 비트 이미지를 지원합니다.
예 원본 이미지 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 3, 7, 10, 10, 10, 10, 5, 5, 5, 5 , 5, 5, 1,. . .
첫 번째 단계 : 반복 찾기 9, 12, 14, 3, 7, 4, 10, 6, 5, 1,. . .
두 번째 단계 : 어떤 요소가 픽셀 값 (0)인지 확인하기 위해지도를 생성합니다. 반복 번호는 (1) 1 0 0 0 0 1 0 1 0입니다. . .
세 번째 단계 : 길이를 8의 배수로 만들려면 0으로 채우십시오. 길이가 8의 배수가되도록 맵을 채 웁니다.
네 번째 단계 : 지도를 8 개로 나누고 모든 조각을 정수로 변환합니다. 133,. . .
다섯 번째 단계 : 두 쌍을 하나씩 8 비트로 만듭니다. 왼쪽으로 4 번 왼쪽으로 이동하고 오른쪽으로 이동합니다. 156, 226, 166, 81,. . .
여섯 번째 단계 : 값으로 맵을 병합하십시오. 맵의 모든 정수는 이제 값에 4 개의 값을 제공합니다. 133, 156, 227, 116, 166 ,. . .
디코딩은이 작업과 반대입니다.