| [casetta] Important : Normalize function and strange behaviour...or not + NEW version of img_to_basic |
[ Thread Index | Date Index | More lists.tuxfamily.org/casetta Archives ]
|
Hello, 2 things : 1st: I have included the modifications you made in the img_to_basic function old version and made that working for me : The changelog until the last version I sent you is : * Changed indent to 4-spaces and lines to 80-characters max. * Changeg color constants to the system of dictionnaries/variables * Included your special condition in the end F-line block : I didn't understand what it is useful for but as it didn't include new bugs, I included this * Corrected the bug of a line not drawn if it goes to the end of a line (Yes I know this is ugly) I still don't know the problem there was in the modified version you sent me. Maybe and indentation problem... I succeded in transmitting my tux2.png on my calculator with your pic2prog.py script. I hope this will work for you. 2nd: Sometimes, I believe that the normalize function has a strange behaviour. For example, the image in attachments contains white (By Thesa). And in the imagen variable sent to the img_to_basic function, there is no white pixel (and of course on my calculator I get no white). I may be wrong ;-) I have also some feature requests (not added in the wishlist, because I want your opinion before : I don't know if it is easy of not !!!) 1- Could you make the dialog window in casetta (such as : "Mettez votre calculatrice en réception et cliquez sur valider"), as it (traduction incertaine de comme çà), you have just to press enter (yes, this is another unimportant detail :-). 2-For backups, could you add the ability to casetta_gtk to show the content ? (Name of programs, matrix,pictures etc ...) 3-For image/screencapture could you display them in casetta and add an export function to export to png... Normally, the img_to_basic function is working and ready to be integrated in the svn :-). "Longue vie à casetta" --
Fabien ANDRE aka Xion345 Registered Linux User #418689 -- see http://counter.li.org for more information fabien.andre.g@xxxxxxxxxx -- xion345@xxxxxxxxxxxxx -- http://xion345.new.fr -- http://perso.wanadoo.fr/xion345 The fact that ACPI was designed by a group of monkeys high on LSD, and is some of the worst designs in the industry obviously makes running it at _any_ point pretty damn ugly. ( Linus Torvalds, July 31, 2005 ) |
# -*- coding: utf-8 -*-
#
############################################################################
#
# (c) 2006 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.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
# 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"""
f=open('/home/fabien_kubuntu/image.txt','w')
f.write(str(imagen))
program_header = "\Cls\n\ViewWindow 0,127,1,0,63,1\n"
orange, green, blue, 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
pictureTable=[]
numberLine=0
basicPicture='' # A picture under the form of a basic program / Returned by
#the function
line=0
while line <= 63:
pictureTable.append(imagen[line*128:((line+1)*128)])
line += 1
print len(pictureTable)
line=0
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] != currentColor and \
pictureTable[line][col-1] == currentColor \
and currentColor in colors[:3] or col==127 and currentColor != \
white and pictureTable[line][col] == currentColor:
# If you get a pixel which color is different from currentColor
# 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 pictureTable 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 (currentColor != white)
if col != 127:
end_x -= 1
if currentColor == orange:
print "Orange"
basicPicture += "\\Orange "
if currentColor == green:
print "Vert"
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'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
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
if pictureTable[line][col] != white 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] != white and \
pictureTable[line][col] == currentColor:
# Continues the F-line
end_x +=1
col += 1
line += 1
return program_header+basicPicture
| Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |