[casetta] Implemented the Image-to-Casio-Basic Function |
[ Thread Index | Date Index | More lists.tuxfamily.org/casetta Archives ]
Hello casetta developers, I requested a new function ofr casetta in the wishlist and i had the pleasure to see that it was added to the roadmap. I began to implement this function (See pictures.py in the attachment). I put this function in the pictures.py but I don't know if it is the good location. This function takes a normalized picture and returns a Casio Basic Program which draws the picture. This function only use the F-line instruction (and only Horizontal F-lines) and Plot-On instructions. Therefore, it is not very optimised to produce Basic Programs which consume few memory. I have also reported a bug #2 about casetta : here is a video to explain what I get. The script I used to test this function is : #-*- coding: utf-8 -*- import casetta.pictures as pic import Image from os import chdir path='/home/fabien_kubuntu/tux_casetta.png' im=Image.open(path) im_table=list(im.getdata()) print len(imn) im_basic=pic.img_to_basic(im_table) print im_basic programme_final="%Header Record\nFormat:TXT\nData Type:PG\nFile Name:TestF\nPassword:\n%Data Record\n"+"\Cls\n"+im_basic chdir('/home/fabien_kubuntu/') file=open('TestF.newcat', 'w') file.write(programme_final) file.close() --
Microsoft is not the answer. Microsoft is the question. NO (or Linux) is the answer. ( Unknown, Not dated ) |
# -*- coding: utf-8 -*- # ############################################################################ # # (c) 2006 Florian Birée aka Thesa <florian.biree@xxxxxxxxxxx> # (c) 2006 Achraf Cherti aka Asher256 <achrafcherti@xxxxxxxxx> # # Website: <URL:http://casetta.tuxfamily.org> # # Version 0.3.0 # # 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" __version__ = "0.3.0" __copyright__ = "Copyright (c) 2006, Florian Birée, Achraf Cherti" __license__ = "GPL" __revision__ = "$Revision: $" # $Source: $ __date__ = "$Date: $" import Image import os import data as datacls # 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'] # 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. """ image.thumbnail(CASIO_SIZE) data = list(image.getdata()) out = [] # color conversion for pixel in data: red, green, blue = pixel[0], pixel[1], pixel[2] if 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) == (255, 255, 255): pixel = colors[3] # white 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 # File format management functions def open_img(filename): """Open an image in any PIL-managed format, return a filedata""" # Build the FileData file_data = datacls.FileData() new_index = file_data.new_data() # Write metadata file_data[new_index].name = 'Picture1' file_data[new_index].dType = 'picture' file_data[new_index].pallet = DEFAULT_PALLET file_data[new_index].color_byte = 0 # Write data img = Image.open(filename) file_data.data[new_index].raw_data = data_to_raw(normalize(img), \ DEFAULT_PALLET) return file_data def save(filename, file_data, export=False): """Save a picture""" folder = os.path.dirname(filename) ext = os.path.splitext(filename) # For each data if export: index_list = file_data.export else: index_list = range(len(file_data.data)) for data in [file_data.data[index] for index in index_list]: if data.dType == 'picture' or data.dType == 'screencapture' : # make a filename from the name if len(index_list) == 1 and os.path.basename(filename) != '': # try to use filename as name data_filename = filename else: data_filename = os.path.join(folder, data.name, ext) # write data img = Image.new('RGB', CASIO_SIZE) img.putdata(raw_to_data(data.raw_data, data.color_byte, data.pallet)) img.save(data_filename) # 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 ############## NEW Function added by Xion345 aka Fabien ANDRE ################### ## Sorry, I didn't really understand how did you manage to obtain a table from ## a "classic" image (png, jpeg etc...). So I may have rewritten some functions, that you have already implemented ! def img_to_basic(imagen): """Convert a *normalized* image into a Casio Basic program This function only returns Horinzontal F-line. It may not be really optimised for size""" # Splits the BIG list given by normalize into a list of list # in order to have a table of 128 columns per 64 lines pictureTable=[] numberLine=0 basicPicture='' # A picture under the form of a basic program / Returned by the function line=0 while numberLine < 64: pictureTable.append(imagen[numberLine*128:((numberLine+1)*128)]) numberLine += 1 print len(pictureTable) while line <= 63: print "Ligne :", line col=0 currentColor=0 # This var contains the previously saved color orig_x=0 orig_y=0 end_x=0 end_y=0 # In fact this varible is totally unuseful because the table is browsed line per line so # end_y = orig_y. It is just used to make my function clearer while col <= 127: #print "pixel ("+str(col)+","+str(line)+")" if pictureTable[line][col] != (255,255,255) and pictureTable[line][col] != currentColor: # New F-line to add detected print "Nouvelle F-ligne détectée en "+str(line)+","+str(col) currentColor=pictureTable[line][col] end_x=col orig_x=col end_y=line orig_y=line if pictureTable[line][col] != (255,255,255) and pictureTable[line][col] == currentColor: # Continue the F-line end_x +=1 if pictureTable[line][col] == (255,255,255) and pictureTable[line][col-1] == currentColor: # If you get a blank pixel and if before you have a colored pixel, that's because you encountered the #end of the F-line end_x -= 1 if currentColor == (255, 128, 0): basicPicture += "\\Orange " if currentColor == (0, 128, 0): basicPicture += "\\Green " # 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 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 if end_x != orig_x: basicPicture += "\\F-Line "+str(orig_x)+","+str(casio_orig_y)+","+str(end_x)+","+str(casio_end_y)+"\n" else: basicPicture += "\\PlotOn "+str(orig_x)+","+str(casio_orig_y)+"\n" currentColor=0 # This var contains the previously saved color orig_x=0 orig_y=0 end_x=0 end_y=0 col += 1 line += 1 return basicPicture
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |