[casetta] Of course, I forgot to attach the new img_to_basic |
[ Thread Index | Date Index | More lists.tuxfamily.org/casetta Archives ]
Hello, Hre is the new img_to_basic function...I'm so absent-minded --
Fabien ANDRE aka Xion345 Linux User #418689 -- fabien.andre.g@xxxxxxxxxx -- xion345@xxxxxxxxxxxxx World domination. Fast. ( Linus Torvalds, Not dated ) |
# -*- coding: utf-8 -*- # ############################################################################ # # (c) 2006-2007 Florian Birée aka Thesa <florian.biree@xxxxxxxxxxx> # (c) 2006 Achraf Cherti aka Asher256 <achrafcherti@xxxxxxxxx> # function img_to_basic is (c) 2007 Xion345 aka Fabien ANDRE # <fabien.andre.g@xxxxxxxxxx> # # Website: <URL:http://casetta.tuxfamily.org> # # Version 0.3.0dev # # changelog: # # # 0.3.0 version: # # o First release # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # http://www.gnu.org/copyleft/gpl.html # ############################################################################ """Pictures manager for casetta""" __author__ = "Florian Birée, Achraf Cherti, Fabien ANDRE" __version__ = "0.3.0dev" __copyright__ = "Copyright (c) 2006-2007, Florian Birée, Achraf Cherti, " + \ "Fabien ANDRE" __license__ = "GPL" __revision__ = "$Revision: $" # $Source: $ __date__ = "$Date: $" import Image # Constants: ORANGE = (255, 128, 0) GREEN = (0, 128, 0) BLUE = (0, 0, 128) WHITE = (255, 255, 255) CASIO_SIZE = (128, 64) COLORS = (ORANGE, GREEN, BLUE, WHITE) _COLOR_DIC = {'o' : ORANGE, 'g' : GREEN, 'b' : BLUE, 'w' : WHITE} DEFAULT_PALLET = ['b', 'g', 'w', 'o'] WHITE_LIMIT = 210 # If all color of a pixel are superior of WHITE_LIMITE, they will be white. # Conversion functions def normalize(image, colors=COLORS): """Convert an image object in a casio-like format. This will: resize image to 128x64 convert color to 4-color mode return a data list. pal is a 4-color tuple. """ if image.size != CASIO_SIZE: image = image.resize(CASIO_SIZE, Image.ANTIALIAS) data = list(image.getdata()) out = [] # color conversion for pixel in data: red, green, blue = pixel[0], pixel[1], pixel[2] if red > WHITE_LIMIT and green > WHITE_LIMIT and blue > WHITE_LIMIT: pixel = colors[3] # white elif red > green and red > blue: pixel = colors[0] # orange elif green > red and green > blue: pixel = colors[1] # green elif blue > green and blue > red: pixel = colors[2] # blue elif red == green and red > blue: pixel = colors[1] # green elif green == blue and green > red: pixel = colors[2] # blue elif red == blue and red > green: pixel = colors[2] # blue elif (red, green, blue) == (0, 0, 0): pixel = colors[2] # blue out.append(pixel) return out def data_to_sheets(data, wanted_pallet=DEFAULT_PALLET): """Make raw picture sheets from *normalized* data wanted_pallet is a list of color id as 'b', 'g', 'w' or 'o' Return a list of data sheets, sorted as wanted_pallet, with the color byte at 0.""" sheets = [] for color_id in wanted_pallet : color = _COLOR_DIC[color_id] rev_sheet = '0' * (128 * 64) for index in range(len(data)): if data[index] == color: line = index / 128 col = (index % 128) / 8 car = (index % 128) % 8 pos = car + line * 8 + col * (8 * 64) rev_sheet = rev_sheet[:pos] + '1' + rev_sheet[pos + 1:] # reverse and compact the rev_sheet sheet = '' for index in range(0, len(data), 8): car = chr(int(rev_sheet[index : index + 8], 2)) sheet = car + sheet sheets.append(chr(wanted_pallet.index(color_id) + 1) + sheet) return sheets def sheets_to_raw(sheets, headers = None): """Join sheets to make raw data The function can add a sheet header form the headers list (one string by sheet). """ raw_img = '' for index in range(len(sheets)): if headers != None: raw_img += headers[index] raw_img += sheets[index] return raw_img def data_to_raw(data, wanted_pallet=DEFAULT_PALLET, headers = None): """Work as sheets_to_raw(data_to_sheets(data)), with same arguments""" return sheets_to_raw(data_to_sheets(data, wanted_pallet), headers) def raw_to_data(raw_picture, color_byte=0, pal=DEFAULT_PALLET, \ colors=COLORS, background=WHITE): """Make image data from a raw picture colors is a 4-color tuple, color_byte is the index of the color_byte (last byte of a sheet header) pal is the ordoned list of the color corresponding to each sheet background is the default color of a pixel.""" #make color dic: color_dic = { 'o' : colors[0], 'g' : colors[1], 'b' : colors[2], 'w' : colors[3]} #extract raw sheets from raw_picture raw_sheets = [] sh_len = 0x400 + color_byte + 1 for index in range(len(pal)): offset = index * sh_len raw_sheets.append(raw_picture[offset: offset + sh_len]) #convert raw sheets to list data data = [background] * (CASIO_SIZE[0] * CASIO_SIZE[1]) for raw_sheet in raw_sheets: color = ord(raw_sheet[color_byte]) - 1 raw_sheet = raw_sheet[color_byte + 1:] for index in range(len(raw_sheet)): byte = bin(ord(raw_sheet[index])) col, line = (15 - ((index) / 64)) * 8, 63 - ((index) % 64) data_pos = line * 128 + (col ) for bit_index in range(len(byte)): if byte[bit_index] == '1': bit_pos = data_pos + bit_index data[bit_pos] = color_dic[pal[color]] return data def raw_to_sheets(raw_picture, color_byte = 0, sheet_number = 4): """Split raw data into sheets""" raw_sheets = [] sh_len = 0x400 + color_byte + 1 for index in range(sheet_number): offset = index * sh_len raw_sheets.append(raw_picture[offset + color_byte: offset + sh_len]) return raw_sheets def change_sheets_pallet(sheets, old_pallet, new_pallet): """Resort sheets from old_pallet to new_pallet If a collor in new_pallet is not in old_pallet, a empty sheet will be made for this color. """ sheet_dic = {} for index in range(len(old_pallet)): sheet_dic[old_pallet[index]] = sheets[index][1:] new_sheets = [] for index in range(len(new_pallet)): new_sheets.append(chr(index + 1) + sheet_dic.get(new_pallet[index], \ '\x00' * (16 * 64))) return new_sheets # Misc functions def bin(number, total_length = 8): """Convert a number in binary, filled with 0 to reach total_length.""" out = '' while number != 0: number, out = number >> 1, `number & 1` + out out = '0' * (total_length - len(out)) + out return out # This function is a contribution of Xion345 aka Fabien ANDRE. # Xion345, thank you! def img_to_basic(imagen, colors=COLORS): """Convert a *normalized* image into a Casio Basic program This function only returns Horinzontal F-line. It may not be really optimised for size""" program_header = "\Cls\n\ViewWindow 0,127,1,0,63,1\n" orange, green, _, white = colors # colors dictionnary # Splits the BIG list given by normalize into a list of list # in order to have a table of 128 columns per 64 lines picture_table = [] basic_pictureh = '' # A picture under the form of a basic program / Returned # by the function - Horizontal lines basic_picturev='' # A picture under the form of a basic program / Returned # by the function - Vertical lines line = 0 plot_table=[] while line <= 63: picture_table.append(imagen[line*128:((line+1)*128)]) line += 1 line = 0 ##### This Big blocks transforms the picture into a program using : ##### HORIZONTAL F-lines only (except for orphan plots, it tries to detect ##### vertical F-lines) while line <= 63: col = 0 current_color = 0 # This var contains the previously saved color orig_x = 0 orig_y = 0 end_x = 0 while col <= 127: if picture_table[line][col] != current_color and \ picture_table[line][col-1] == current_color \ and current_color in colors[:3] or col==127 and current_color != \ white and picture_table[line][col] == current_color: # If you get a pixel which color is different from current_color # and if before you have a colored pixel, #that's because you encountered the end of the F-line # The second condition after the or is an UGLY correction of a # BUG ^W Feature # If an F-line goes at the lats pixel of a picture_table line, # the line is not drawn because the first confition (end line # see above ), waits for the pixel just after the end of the # line. This blocks checks if were are at the last pixel of the # line and if a F-line is being drawn (current_color != white) if col != 127: end_x -= 1 # The origin of the reference mark is different #on the casio graph and on the picture # On casio origin is bottom left-hand corner # On the picture and my table, it's top left-hand corner # That's why it must do casio_line = 63-line casio_orig_y = 63-orig_y if end_x-orig_x>1: if current_color == orange: basic_pictureh += "\\Orange " if current_color == green: basic_pictureh += "\\Green " if end_x-orig_x!=127: basic_pictureh += "\\F-Line " \ + str(orig_x) + "," + str(casio_orig_y) + "," \ + str(end_x) + "," + str(casio_orig_y) + "\n" else: basic_pictureh += "\\Horizontal "+str(casio_orig_y)+"\n" # elif end_x==orig_x: # basic_pictureh += "\\PlotOn " \ # + str(orig_x) + ","+str(casio_orig_y) + "\n" # # Rather than drawing directly orphan Plot-on, # they are stored in # a table in order to detec if they could be drawn as a # **VERTICAL** F-line plot_table.append((current_color, orig_x, casio_orig_y)) elif end_x-orig_x==1: # Rather than writing a 2-pixel long F-line, # we store two plots # in plot_table, expecting that it is part of a longer # F-line plot_table.append((current_color, orig_x, casio_orig_y)) plot_table.append((current_color, end_x, casio_orig_y)) current_color = 0 # This var contains the previously saved color orig_x = 0 orig_y = 0 end_x = 0 if picture_table[line][col] != white and \ picture_table[line][col] != current_color: # New F-line to add detected current_color = picture_table[line][col] end_x = col orig_x = col orig_y = line if picture_table[line][col] != white and \ picture_table[line][col] == current_color: # Continues the F-line end_x += 1 col += 1 line += 1 ### This bloc tries to draw VERTICAL F-lines from stored orphan plots ### in plot-table while len(plot_table) > 0: #print plot_table current_color=plot_table[0][0] orig_x=plot_table[0][1] casio_orig_y=casio_end_y=plot_table[0][2] plot_table.pop(0) i=0 while i < len(plot_table): #print '*'+str(plot_table.index(i)) #print plot_table if plot_table[i][0]==current_color and \ plot_table[i][1]==orig_x and plot_table[i][2]==casio_end_y-1: casio_end_y=plot_table[i][2] plot_table.pop(i) i -= 1 i += 1 # End of VERTICAL F-line, all plots were checked if current_color == orange: basic_pictureh += "\\Orange " if current_color == green: basic_pictureh += "\\Green " if casio_orig_y != casio_end_y: basic_pictureh += "\\F-Line " \ + str(orig_x) + "," + str(casio_orig_y) + "," \ + str(orig_x) + "," + str(casio_end_y) + "\n" else: basic_pictureh += "\\PlotOn " \ + str(orig_x) + ","+str(casio_orig_y) + "\n" ##### This Big blocks transforms the picture into a program using : ##### VERTICAL F-lines only (except for orphan plots, it tries to detect ##### horizontal F-lines) col=0 while col <= 127: line = 0 current_color = 0 # This var contains the previously saved color orig_x = 0 orig_y = 0 end_y = 0 while line <= 63: if picture_table[line][col] != current_color and \ picture_table[line-1][col] == current_color \ and current_color in colors[:3] or line==63 and current_color != \ white and picture_table[line][col] == current_color: # If you get a pixel which color is different from current_color # and if before you have a colored pixel, #that's because you encountered the end of the F-line # The second condition after the or is an UGLY correction of a # BUG ^W Feature # If an F-line goes at the lats pixel of a picture_table line, # the line is not drawn because the first confition (end line # see above ), waits for the pixel just after the end of the # line. This blocks checks if were are at the last pixel of the # line and if a F-line is being drawn (current_color != white) if line != 63: end_y -= 1 # The origin of the reference mark is different # on the casio graph and on the picture # On casio origin is bottom left-hand corner # On the picture and my table, it's top left-hand corner # That's why it must do casio_line = 63-line casio_orig_y = 63-orig_y casio_end_y = 63-end_y print str(casio_orig_y)+'-'+str(casio_end_y) if abs(casio_end_y-casio_orig_y)>1: if current_color == orange: basic_picturev += "\\Orange " if current_color == green: basic_picturev += "\\Green " if abs(casio_end_y-casio_orig_y) != 63: basic_picturev += "\\F-Line " \ + str(orig_x) + "," + str(casio_orig_y) + "," \ + str(orig_x) + "," + str(casio_end_y) + "\n" else: basic_picturev += "\\Vertical "+str(orig_x)+"\n" elif casio_end_y==casio_orig_y: # Rather than drawing directly orphan Plot-on, # they are stored in # a table in order to detec if they could be drawn as a # **VERTICAL** F-line # plot_table.append((current_color, orig_x, casio_orig_y)) elif abs(casio_end_y-casio_orig_y)==1: # Rather than writing a 2-pixel F-line, we store two plots # in plot_table, expecting that it is part of a longer # F-line # plot_table.append((current_color, orig_x, casio_orig_y)) plot_table.append((current_color, end_x, casio_end_y)) current_color = 0 # This var contains the previously saved color orig_x = 0 orig_y = 0 end_y = 0 if picture_table[line][col] != white and \ picture_table[line][col] != current_color: # New F-line to add detected current_color = picture_table[line][col] end_y = line orig_x = col orig_y = line if picture_table[line][col] != white and \ picture_table[line][col] == current_color: # Continues the F-line end_y += 1 line += 1 col += 1 ### This bloc tries to draw HORIZONTAL F-lines from stored orphan plots print plot_table while len(plot_table) > 0: current_color=plot_table[0][0] end_x=orig_x=plot_table[0][1] casio_orig_y=plot_table[0][2] plot_table.pop(0) i=0 while i < len(plot_table): if plot_table[i][0]==current_color and \ plot_table[i][2]==casio_orig_y and plot_table[i][1]==end_x+1: end_x=plot_table[i][1] plot_table.pop(i) i -= 1 i += 1 # End of HORIZONTAL F-line, all plots were checked if current_color == orange: basic_picturev += "\\Orange " if current_color == green: basic_picturev += "\\Green " if orig_x != end_x: basic_picturev += "\\F-Line " \ + str(orig_x) + "," + str(casio_orig_y) + "," \ + str(end_x) + "," + str(casio_orig_y) + "\n" else: basic_picturev += "\\PlotOn " \ + str(orig_x) + ","+str(casio_orig_y) + "\n" ### Then the function returns the lightest picture : using horizontal F-lines ### or using vertical F-lines if len(basic_pictureh) <= len(basic_picturev): return program_header + basic_pictureh else: return program_header + basic_picturev
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |