def loadSurfaceOptimised(windowSurface, path): #newTexture = SDL_Texture() bpath = path.encode() optimizedSurface = None loadedSurface = sdlimage.IMG_Load(bpath) if (loadedSurface == None): print("Unable to load image {}! SDL_image Error: ".format(bpath), IMG_GetError()) else: #Convert surface to screen format optimizedSurface = SDL_ConvertSurface(loadedSurface, t_screenSurface.format, 0) if (optimizedSurface == None): printf("Unable to optimize image {}! SDL Error: ".format(bpath), SDL_GetError()) #Get rid of old loaded surface SDL_FreeSurface(loadedSurface) Golem.Surface.wrap(newSurface) return optimizedSurface
def reprocessImage(file, ren, all_blocks): surface = sdl_image.IMG_Load(file.encode("utf-8")) pixels = sdl2.ext.PixelView(surface.contents) image = Image() texture = sdl2.SDL_CreateTextureFromSurface(ren.sdlrenderer, surface) for y in range(0, 6): for x in range(0, 8): this_block = Block.fromPixels(pixels, x, y) # find match for block best_match = 64 match_index = -1 for index in range(len(all_blocks)): match = this_block.diffWithTolerance(all_blocks[index], best_match) if match <= best_match: # found best match so far match_index = index best_match = match if best_match == 0: # perfect match found so break # don't look further if match_index >= 0: image.append(match_index) # store best match else: print("no match found within tolerance - problem") exit(1) # draw source image sdl2.SDL_RenderCopy(ren.sdlrenderer, texture, sdl2.SDL_Rect(0, 0, 64, 48), sdl2.SDL_Rect(0, 0, 128, 96)) return image
def addDiffuseTexture(self, textureImage): GL.glActiveTexture(GL.GL_TEXTURE0) self.textureObject = GL.glGenTextures(1) surface = sdlimage.IMG_Load(bytes(textureImage, 'UTF-8')) pixels = ctypes.cast(surface.contents.pixels, ctypes.c_void_p) width = surface.contents.w height = surface.contents.h bmask = surface.contents.format.contents.Bmask imgFormat = GL.GL_RGBA if bmask == 255: imgFormat = GL.GL_BGRA GL.glBindTexture(GL.GL_TEXTURE_2D, self.textureObject) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, imgFormat, GL.GL_UNSIGNED_BYTE, pixels) GL.glGenerateMipmap(GL.GL_TEXTURE_2D) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE) GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
def test_IMG_Load(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) sf = sdlimage.IMG_Load(filename.encode("utf-8")) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf)
def load(self, path, canvas: Canvas): """ Load the image from the specified filename. """ self.surface = img.IMG_Load(str.encode(path)) self.w = self.surface.contents.w self.h = self.surface.contents.h self.texture = sdl2.SDL_CreateTextureFromSurface( canvas.renderer, self.surface)
def load(self, key, img, renderer=None): # Load surface surf = sdlimage.IMG_Load(str.encode(img['src'])) # is there a background color ? if img.get('background'): SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf.contents.format, *img.get('background'))) texture = SDL_CreateTextureFromSurface(renderer, surf) self._imgbank[key] = texture
def processImage(file, ren): surface = sdl_image.IMG_Load(file.encode("utf-8")) pixels = sdl2.ext.PixelView(surface.contents) image = Image() blocks = [Block.black(), Block.white()] # w = surface.contents.w # h = surface.contents.h # print(f"Opened image - width:{w}, height:{h}.") # print("Processing image...") texture = sdl2.SDL_CreateTextureFromSurface(ren.sdlrenderer, surface) new_block = 0 for y in range(0, 12): for x in range(0, 16): this_block = Block() # get the next block from image for by in range(0, 8): for bx in range(0, 8): # print(f"0x{pixels[y][x]:01x}") if pixels[y * 8 + by][x * 8 + bx] == 0xffffffff: this_block.append(1) # print("1", end='') else: this_block.append(0) # print("0", end='') # print('') # this_block.append(pixels[y][x]) # check if this block has been used already found = False for index in range(len(blocks)): if this_block.diffWithTolerance(blocks[index], 5) < 5: # if this_block==old_block: found = True # store record of which block this is in output image.append(index) break if not found: # if not store it image.append(len(blocks)) # store record of which block this is in output blocks.append(this_block) # draw source image sdl2.SDL_RenderCopy(ren.sdlrenderer, texture, sdl2.SDL_Rect(0, 0, 128, 96), sdl2.SDL_Rect(0, 0, 128, 96)) # output # print(f"Image: {file}") # for y in range(0, 12): # for x in range(0, 16): # print(f" {image[x + y * 16]}", end="") # print("") # print("Blocks:",len(blocks)) return image, blocks
def initTexture(self): GL.glActiveTexture(GL.GL_TEXTURE0) self.textureObject = GL.glGenTextures(1) rockmanImage = sdlimage.IMG_Load(b'rockman.png') pixels = ctypes.cast(rockmanImage.contents.pixels, ctypes.c_void_p) GL.glBindTexture(GL.GL_TEXTURE_2D, self.textureObject) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, 128, 128, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST)
def load_image(self, name, src, renderer): surf = sdlimage.IMG_Load(str.encode(src)) # SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf.contents.format, 128, 128, 255)) # SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf.contents.format, 255, 255, 255)) SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf.contents.format, 170, 170, 170)) texture = SDL_CreateTextureFromSurface(renderer, surf) # then remove surface SDL_FreeSurface(surf) self._images[name] = texture
def processImage(file, ren): surface = sdl_image.IMG_Load(file.encode("utf-8")) pixels = sdl2.ext.PixelView(surface.contents) image = Image() # w = surface.contents.w # h = surface.contents.h # print(f"Opened image - width:{w}, height:{h}.") # print("Processing image...") texture = sdl2.SDL_CreateTextureFromSurface(ren.sdlrenderer, surface) max_count = 0 count = 0 col = (pixels[0] == 0xffffffff) image.append(col) # store whether frame starts with black or white image.append(0) # for bits count for y in range(0, 48): for x in range(0, 64): pix = (pixels[y][x] == 0xffffffff) if col == pix: count += 1 else: image.append(count) max_count = max(count, max_count) count = 0 col = pix if count > 0: image.append(count) max_count = max(count, max_count) bits = 0 while 2**bits < max_count: bits += 1 image[1] = bits # draw source image sdl2.SDL_RenderCopy(ren.sdlrenderer, texture, sdl2.SDL_Rect(0, 0, 64, 48), sdl2.SDL_Rect(0, 0, 128, 96)) sdl2.SDL_DestroyTexture(texture) # output # print(f"Image: {file}") # for y in range(0, 12): # for x in range(0, 16): # print(f" {image[x + y * 16]}", end="") # print("") # print("Blocks:",len(blocks)) return image
def processImage(file, ren): surface = sdl_image.IMG_Load(file.encode("utf-8")) pixels = sdl2.ext.PixelView(surface.contents) image = Image() blocks = [Block.black(), Block.white()] # w = surface.contents.w # h = surface.contents.h # print(f"Opened image - width:{w}, height:{h}.") # print("Processing image...") texture = sdl2.SDL_CreateTextureFromSurface(ren.sdlrenderer, surface) new_block = 0 for y in range(0, 6): for x in range(0, 8): this_block = Block.fromPixels(pixels, x, y) # check if this block has been used already found = False num_blocks = len(blocks) for index in range(num_blocks): # if this_block.diffWithTolerance(blocks[index],5)<5: if this_block == blocks[index]: found = True # store record of which block this is in output image.append( index ) # storing images on first pass isn't needed, but let's me draw preview blocks[index].count += 1 break if not found: # if not store it image.append(len(blocks)) # store record of which block this is in output blocks.append(this_block) # draw source image sdl2.SDL_RenderCopy(ren.sdlrenderer, texture, sdl2.SDL_Rect(0, 0, 64, 48), sdl2.SDL_Rect(0, 0, 128, 96)) # output # print(f"Image: {file}") # for y in range(0, 12): # for x in range(0, 16): # print(f" {image[x + y * 16]}", end="") # print("") # print("Blocks:",len(blocks)) return image, blocks
def loadSurface(path): #newTexture = SDL_Texture() bpath = path.encode() loadedSurface = sdlimage.IMG_Load(bpath) if loadedSurface == None: print("Unable to load surface from path :", bpath) # else: # loadedSurface Golem.Surface.wrap(loadedSurface) return loadedSurface
def loadTexture(t_renderer, path): #newTexture = SDL_Texture() bpath = path.encode() newTexture = None loadedSurface = sdlimage.IMG_Load(bpath) if loadedSurface: newTexture = SDL_CreateTextureFromSurface(t_renderer, loadedSurface) if not newTexture: print("Unable to create texture from {}! SDL Error: {}".format( bpath.c_str(), SDL_GetError())) SDL_FreeSurface(loadedSurface) #Golem.Texture.wrap(newSurface) return newTexture
def fromFile(cls, ren, file, width=None, height=None, trim=False): # get image into surface (don't need to keep this though) surface = sdl_image.IMG_Load(file.encode("utf-8")) texture = None trim_x = 0 trim_y = 0 if trim: # grab the pixel values # scrub through them # set the left to be the least value of x that isn't empty by # setting the initial value to the far right # and updating it every time we hit a non-zero pixel that has # has a further left i.e. lower x value # set the top to be the least value of y that isn't empty # set the right to be the highest value of y that isn't empty # by setting the initial value to be the left (0) # set the bottom to be the highest value of y that isn't empty h = surface.contents.h w = surface.contents.w top = h - 1 bottom = 0 right = 0 left = w - 1 pixels = sdl2.ext.PixelView(surface.contents) format = surface.contents.format.contents.format # top for y in range(0, h): for x in range(0, w): if pixels[y][x] != 0: if top > y: top = y if bottom < y: bottom = y if left > x: left = x if right < x: right = x # print(f"file: {file}") # print(f"top {top}, bottom {bottom}") # print(f"left {left}, right {right}") new_w = right - left + 1 new_h = bottom - top + 1 if not (new_w >= w and new_h >= h): width = min(new_w, w) height = min(new_h, h) trim_x = max(0, left) trim_y = max(0, top) # there's space around the sprite so trim it trim_surface = sdl2.SDL_CreateRGBSurfaceWithFormatFrom( surface.contents.pixels + left * 4 + top * w * 4, new_w, new_h, 32, w * 4, format # 0xff,0xff00,0xff0000,0xff000000 ) if not trim_surface: print("SDL_CreateRGBSurfaceFrom failed") exit(1) texture = sdl2.SDL_CreateTextureFromSurface( ren.sdlrenderer, trim_surface) # make a texture from the sdl surface (for HW rendering) if not texture: texture = sdl2.SDL_CreateTextureFromSurface( ren.sdlrenderer, surface) if not (width and height): width = surface.contents.w height = surface.contents.h if not trim: sdl2.SDL_FreeSurface(surface) return cls(ren=ren.sdlrenderer, texture=texture, width=width, height=height, file=file, trim_x=trim_x, trim_y=trim_y)
def processPNG(filename, six_bit=False): surface = sdl_image.IMG_Load((filename + ".png").encode("utf-8")) pixels = sdl2.ext.PixelView(surface.contents) w = surface.contents.w h = surface.contents.h # rect to analyse start_x = 0 # note: inclusive start_y = 0 end_x = w # note: not inclusive end_y = h num_pixels = (end_y - start_y) * (end_x - start_x) print("###############################################") print(f"Opened image {filename}.png - width:{w}, height:{h}.") print("Processing image...") p8_standpal_image, p8_custpal_image, image_pal, standard_colours, p8_mismatches = analyseRect( pixels, start_x, start_y, end_x, end_y) standard_colours_override = False if len(p8_mismatches) > 0: print("Warning: mismatches with pico-8 palette:") for col in p8_mismatches: print(f"0x{col:02x}") else: print("No colour mismatches with pico-8 palette (this is good).") if standard_colours or standard_colours_override: print("Image uses only standard colours.") print("= Standard palette image =") standard_palette_image = standardPaletteImage(p8_standpal_image) # print(standard_palette_image) print(f"Length: {len(standard_palette_image)} characters") else: print("Image uses extended palette") print(f"Image has {len(image_pal)} colours.") if len(image_pal) > 16: print( "Warning: displaying more than 16 colours on pico-8 may be tricky." ) # output tables for pico-8 print("= Custom palette image =") # print(listToString(p8_custpal_image)) print(f"Length: {len(p8_custpal_image)} characters") print(f"Custom palette ({len(image_pal)} colours)") print("{", end="") for col in image_pal: print(f"{col},", end='') print("}") # try to make image data smaller length = len(image_pal) - 1 min_bits = 0 while length > 0: min_bits += 1 length = math.floor(length / 2) print( f"{len(image_pal)} colours could be encoded in {min_bits} bits per pixel" ) ################################################################## # Run Length Encode print("Raw image RLE:") RLE_data, max_count, pairs = runLengthEncode(p8_custpal_image, min_bits) # for i in range(len(counts)): # print(f"Found {counts[i]} of {values[i]}") # print(f"Max count is {max_count}") # print(listToString(RLE_data)) print(f"Length: {len(RLE_data)} characters") print(f"Max count: {max_count} duplicates") print(f"Pairs: {pairs} count/values") print(f"Compression {len(RLE_data)/len(p8_custpal_image)*100}%") # verify by decoding decoded_data = listToString(runLengthDecode(RLE_data)) if listToString(decoded_data) != listToString(p8_custpal_image): print("Warning: problem with RLE.") print("org:" + listToString(p8_custpal_image)) print("out:" + listToString(decoded_data)) else: print(" (decode matches)") # for i in range(int(len(RLE_string)/2)): # print(f"{RLE_string[i*2]}{RLE_string[i*2+1]},", end="") ################################################################## # Run Length Encode only zeros print("Raw image RLE, zeros only (RLE0):") RLE0_data, max_count, zero_blocks = runLengthEncodeOnlyZeros( p8_custpal_image, min_bits) # print(listToString(RLE0_data)) print(f"Length: {len(RLE0_data)} characters") print(f"Max count: {max_count} duplicates") print(f"Zero blocks: {zero_blocks}") print(f"Compression: {len(RLE0_data)/len(p8_custpal_image)*100}%") print( f"After estimate of growth due to zero blocks:{len(RLE0_data)/len(p8_custpal_image)*100}" ) # verify by decoding decoded_data = listToString(runLengthDecodeOnlyZeros(RLE0_data)) if listToString(decoded_data) != listToString(p8_custpal_image): print("Warning: problem with RLE0.") print("org:" + listToString(p8_custpal_image)) print("out:" + listToString(decoded_data)) else: print(" (decode matches)") # for i in range(int(len(RLE_string)/2)): # print(f"{RLE_string[i*2]}{RLE_string[i*2+1]},", end="") ################################################################## # Squeeze to different encodings: 6bit and 8bit chars if six_bit: # encode to base64 as standard colours if possible if min_bits == 4 and standard_colours or standard_colours_override: image_64_standard_string = squeeze4to64(standard_palette_image) print( "= Squeezed to base64 ascii from character 35 with standard palette: =" ) print(image_64_standard_string) print(f"Length: {len(image_64_standard_string)} characters") # verify by inflating again infl_string = inflate64to4(image_64_standard_string, num_pixels) if infl_string != standard_palette_image: print( "Warning: problem with base64 encoding of non-RLE image.") print("org:" + standard_palette_image) print("out:" + infl_string) else: print(" (inflation matches)") image_64_data = [ None, squeeze1to64, squeeze2to64, squeeze3to64, squeeze4to64 ][min_bits](p8_custpal_image) print("= Squeezed to base64 ascii from character 35: =") print(listToString(image_64_data)) print(f"Length: {len(image_64_data)} characters") # verify by inflating again infl_data = [ None, inflate64to1, inflate64to2, inflate64to3, inflate64to4, ][min_bits](image_64_data, num_pixels) if listToString(infl_data) != listToString(p8_custpal_image): print("Warning: problem with base64 encoding of non-RLE image.") print("org:" + listToString(p8_custpal_image)) print("out:" + listToString(infl_data)) else: print(" (inflation matches)") print("= RLE squeezed to base64 ascii from character 35: =") RLE_64_string = [ None, squeeze1to64, squeeze2to64, squeeze3to64, squeeze4to64 ][min_bits](RLE_data) print(RLE_64_string) print(f"Length: {len(RLE_64_string)} characters") # verify by inflating again infl_data = [ None, inflate64to1, inflate64to2, inflate64to3, inflate64to4, ][min_bits](RLE_64_string, len(RLE_data)) if listToString(infl_data) != listToString(RLE_data): print("Warning: problem with base64 encoding.") print("org:" + listToString(RLE_data)) print("out:" + listToString(infl_data)) else: print(" (inflation matches)") decoded_data = runLengthDecode(infl_data) if listToString(decoded_data) != listToString(p8_custpal_image): print("Warning: problem with RLE.") print("org:" + listToString(p8_custpal_image)) print("out:" + listToString(decoded_data)) else: print(" (decode matches)") # for i in range(len(counts)): # print(f"Found {counts[i]} of {values[i]}") # print(f"Max count is {max_count}") print(f"Squeezing vs raw: {len(image_64_data)/num_pixels*100}%") print( f"RLE and squeezing size vs raw: {len(RLE_64_string)/num_pixels*100}%" ) esc_string = escape_binary_str(RLE_64_string) print(f"Escaped string (length {len(esc_string)}):") print(esc_string) print("###################################################") print("# 8 bit #") print("###################################################") print("= Raw squeezed to 8bit (base 256) characters: =") raw_8bit_data = squeezeTo8bit(p8_custpal_image, min_bits) dumpP8File(encode8bitDataAsPICO8String(raw_8bit_data), "raw8bit") # verify by inflating again infl_data = inflate8bit(raw_8bit_data, len(p8_custpal_image), min_bits) if listToString(infl_data) != listToString(p8_custpal_image): print("Warning: problem with 8bit encoding.") print("org:" + listToString(p8_custpal_image)) print("out:" + listToString(infl_data)) else: print(" (inflation matches)") out, best_trans = findBestEncode(raw_8bit_data) print( f"Best encoding with trans value: {best_trans} Length: {len(out)} vs {len(raw_8bit_data)}" ) print("= RLE squeezed to 8bit (base 256) characters: =") RLE_8bit_data = squeezeTo8bit(RLE_data, min_bits) dumpP8File(encode8bitDataAsPICO8String(RLE_8bit_data), "RLE8bit") # verify by inflating again infl_data = inflate8bit(RLE_8bit_data, len(RLE_data), min_bits) if listToString(infl_data) != listToString(RLE_data): print("Warning: problem with 8bit encoding.") print("org:" + listToString(RLE_data)) print("out:" + listToString(infl_data)) else: print(" (inflation matches)") out, best_trans = findBestEncode(RLE_8bit_data) print( f"Best encoding with trans value: {best_trans} Length: {len(out)} vs {len(RLE_8bit_data)}" ) print("= RLE0 squeezed to 8bit (base 256) characters: =") RLE0_8bit_data = squeezeTo8bit(RLE0_data, min_bits) dumpP8File(encode8bitDataAsPICO8String(RLE0_8bit_data), "RLE0_8bit") # verify by inflating again infl_data = inflate8bit(RLE0_8bit_data, len(RLE0_data), min_bits) if listToString(infl_data) != listToString(RLE0_data): print("Warning: problem with 8bit encoding.") print("org:" + listToString(RLE0_data)) print("out:" + listToString(infl_data)) else: print(" (inflation matches)") out, best_trans = findBestEncode(RLE0_8bit_data) print( f"Best encoding with trans value: {best_trans} Length: {len(out)} vs {len(RLE0_8bit_data)}" ) print("= DBI Output =") # override palette here #image_pal=[2,1,8,4,13,3,0,7,6,9,15] if len(RLE_8bit_data) <= len(RLE0_8bit_data) and len(RLE_8bit_data) < len( raw_8bit_data): best_data = RLE_8bit_data best_type = 1 print("Using RLE data") elif len(RLE0_8bit_data) <= len(RLE_8bit_data) and len( RLE0_8bit_data) < len(raw_8bit_data): best_data = RLE0_8bit_data best_type = 2 print("Using RLE0 data") else: best_data = raw_8bit_data best_type = 0 print("Using uncompressed data") DBI_raw_data, DBI_encoded_data, trans = makeDBIData( width=w, height=h, palette=image_pal, data=best_data, data_type=best_type, num_values=len(RLE0_data)) dumpP8File(DBI_encoded_data, filename + "_dbi") return DBI_raw_data