arrays - 通过将文件中的二进制值转换为 3-3-2 颜色,将 8 位颜色显示到屏幕上
问题描述
我最近一直在研究一个小型仿真 8 位 CPU,我希望它具有图形功能。目前,它在每个周期将 ram 的上部 16K 转储为二进制文件,以便将其作为“视频内存”读取。我制作了一个简单的基于 pygame 的程序,它读取文件,然后尝试将其转换为 128x128 灰度 3d 数组,以便直接将其作为表面进行 blit。这没用。我想我可以直接切入正题,问,有没有办法读取二进制文件并将其字节转换为 3-3-2 颜色,而不管文件的实际内容如何?
这是我当前的代码:
import pygame
import numpy as np
from time import sleep
class Viewer:
def __init__(self, update_func, display_size):
self.display_size = display_size
self.update_func = update_func
pygame.init()
self.display = pygame.display.set_mode(display_size)
def set_title(self, title):
pygame.display.set_caption(title)
def start(self):
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
z = self.update_func()
surf = pygame.surfarray.make_surface(z)
new = pygame.transform.scale(surf, self.display_size)
self.display.blit(new, (0, 0))
pygame.display.update()
pygame.quit()
def update():
file = open("core.bin", "rb")
value = bytearray(file.read())
lst = list(value)
file.close()
image = [[ [lst for col in range(len(lst))] for col in range(len(lst))] for row in range(len(lst))]
print(image)
sleep(0.25)
return image
viewer = Viewer(update, (512, 512))
viewer.start()
update()
我过去曾尝试过 numpy.dstack,普通的 3d 数组在我的代码中运行良好,只是二进制文件不行。是的,我的 bin 文件正好是 16k。也没有错误信息。
解决方案
制作了一张128*128的8位图片,供测试;假设 RRRGGGBB,而不是 BBGGGRRR。翻转他们,如果是这样的话。发现 numpy 的reshape()
残骸图像。将值直接注入预期的 numpy 位置会产生更好的结果。也应该更快。
#! /usr/bin/env python3
import pygame
import numpy as np
from time import sleep
from random import randint
class Viewer:
def __init__(self, update_func, display_size):
self.display_size = display_size
self.update_func = update_func
pygame.init()
self.display = pygame.display.set_mode(display_size)
def set_title(self, title):
pygame.display.set_caption(title)
def start(self):
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
z = self.update_func()
surf = pygame.surfarray.make_surface(z)
new = pygame.transform.scale(surf, self.display_size)
self.display.blit(new, (0, 0))
pygame.display.update()
pygame.quit()
'''
32 111 000 00 = randint( 0, 7 ) << 5 r
64 000 111 00 = randint( 0, 7 ) << 2 g
96 000 000 11 = randint( 0, 3 ) b
128 111 111 11 = randint( 0, 255 ) w
'''
screenshot = bytearray( 128 *128 ) ## 128 *128 8-bit image, just for testing
for red in range( 0, 128 *32 ): screenshot[ red ] = randint( 0, 7 ) << 5
for green in range( 128 *32, 128 *64 ): screenshot[ green ] = randint( 0, 7 ) << 2
for blue in range( 128 *64, 128 *96 ): screenshot[ blue ] = randint( 0, 3 )
for white in range( 128 *96, 128 *128 ): screenshot[ white ] = randint( 0, 255 )
row, col = 0, 0
arr = np .zeros( ( 128, 128, 3 ) ) ## generate empty numpy array
for byte in screenshot:
rrr = int( ( ( byte & 0b11100000 ) >> 5 ) *36.4285714286 ) ## red
ggg = int( ( ( byte & 0b00011100 ) >> 2 ) *36.4285714286 ) ## green
bb = int( ( byte & 0b00000011 ) *85 ) ## blue -- multiplied to max 255 range
arr[ col ][ row ][ 0 ] = rrr ## insert color values directly into numpy cells
arr[ col ][ row ][ 1 ] = ggg
arr[ col ][ row ][ 2 ] = bb
col += 1
if col == 128:
col = 0 ## \r carriage return
row += 1 ## \n newline
def update():
image = arr
sleep(0.25)
return image
viewer = Viewer(update, (512, 512))
viewer.start()
update()
推荐阅读
- php - 以不同的用户身份运行 httpd?
- javascript - clientX 和 clientY 在缩放的 IE 中返回十进制值
- javascript - 需要自定义工具提示
- android - 单个 Android 应用上的两个 Firebase 云消息
- c++ - 使用 MinGW 编译器编译 C++ 程序时如何增加堆栈大小
- android - 在 android 应用程序中创建服务器使用的唯一 ID 的最佳方法
- c++ - 以独占模式预取缓存行
- python - Python中允许实时调整的交互式绘图,可能吗?
- angular - 我将在哪里发送背景消息选项
- python - 为什么在 on_connect 之前调用 on_publish 回调?