Sorry for talking to myself.
Yes it is possible albeit a bit tricky. Normally when you inherit from a class in Python you must call the __init__ constructor of the base class before calling any other method. Python requires this (the constructor is not automatically called as e. g. in C++). But an Image is not created with the constructor but with the method new. So you first have to create an Image with the new method and afterwards call the __init__ constructor with the the Image you got from new as argument.
I include a fully working example (indeed a small app). Some notes: You must of course change the filenames, so that they point to Pictures on your phone. Don't add too many pictures, because they need a lot of RAM (that's why the last picture is commented out - memory was full on my E90). Currently it's tested with 2 different Picture sizes (the second Eva20Geburtstag... has 1280x960 the other are normal 3.2 M-Pixel pics (2048x1532 or so) from the E90 camera.
Import file Picjog.py which defines a class inherited from graphics.Image:
Code:
# Picjoger import file
# Copyright (c) 2009 Hans-Peter Sulzer, Fürth, all rights reserved
"""
Classes, functions, etc. for Picjoger app
"""
import appuifw, e32, key_codes, graphics #, _graphics
class hpspic(graphics.Image):
"""Image class inherited from graphics.Image with additional
attributes and methods"""
def __init__(self,filename,handle_redraw):
self.__fn=filename
self.handle_redraw=handle_redraw
attrib=graphics.Image.inspect(filename)
self.__w, self.__h=attrib["size"]
self.__w=self.__w*1.; self.__h=self.__h*1.
#Now call the new-method of the base class
#try to remove the below hard qualification of the
#base class name ("graphics.Image") ):
img = graphics.Image.new( \
size=attrib["size"],mode="RGB")
#img=_graphics.ImageNew(attrib["size"], \
# graphics.Image._modemap["RGB"])
#img not checked in this version!
# MUST BE DONE !
#Now we must call the constructor of the base class with
#the image object we just got(!):
graphics.Image.__init__(self,img)
# Now the additional attributes and methods we need:
self.__complete=False #set to True by callback method loaded()
self.showed=False
# perhaps insert, if picture is already shown in HQ (i. e. pic
# has been resized with "resize"-method of "graphics.Image"):
#self.hq=False
def loaded(self,error): #callback function, when pic is loaded
if not error:
self.__complete=True
if self.showed:
#Following doesn't work (Global name canvas not defined):
#canvas.blit(self,target=((0,0),\
#(wb,hb)),\
#source=((0,500),(self.__w,int(500+hb*fullwfact))),scale=0)
self.handle_redraw(None)
pass
#difficult, we don't know if pic is zoomed!
def load(self,callback=None):
if not callback:
callback=self.loaded
graphics.Image.load(self,self.__fn,callback)
def w(self):
return self.__w
def h(self):
return self.__h
Now we can use objects of this class, like a normal graphics.Image object, like in the following example application. Shows the pictures as fast as e. g. on an iPhone. When pressing the select button, the image is togled between full size and fullscreen mode (upper/lower or left/right areas clipped).
File Picjoger.py for showing Fotos very fast and easy:
Code:
#!Python
# Copyright (c) 2009 Hans-Peter Sulzer, Fürth, all rights reserved
"""
Picture viewer application
"""
from picjog import *
def handle_redraw(rect):
if pics:
if wb/hb >= pics[ip].w()/pics[ip].h():
if fullsize:
ws=int(pics[ip].w()*hb/pics[ip].h())
left=int((wb-ws)/2)
canvas.clear()
canvas.blit(pics[ip],target=((left,0),(left+ws,hb)), \
source=((0,0),(pics[ip].w(),pics[ip].h())),scale=1)
else:
hs=int(hb*pics[ip].w()/wb)
topsrc=int((pics[ip].h()-hs)/2)
canvas.blit(pics[ip],target=((0,0), \
(wb,hb)),source=((0,topsrc), \
(pics[ip].w(),topsrc+hs)),scale=1)
else:
if fullsize:
hs=int(pics[ip].h()*wb/pics[ip].w())
canvas.clear()
canvas.blit(pics[ip],target=((0,0),(wb,hs)), \
source=((0,0),(pics[ip].w(),pics[ip].h())),scale=1)
else:
ws=int(wb*pics[ip].h()/hb)
leftsrc=int((pics[ip].w()-ws)/2)
canvas.blit(pics[ip],target=((0,0),(wb,hb)), \
source=((leftsrc,0), \
(leftsrc+ws,pics[ip].h())),scale=1)
def handle_event(event):
global fullsize, ip
ev = event["keycode"]
if event["type"] == appuifw.EEventKey:
if ev == key_codes.EKeySelect:
if fullsize:
fullsize=False
else:
fullsize=True
elif ev == key_codes.EKeyUpArrow:
pass
elif ev == key_codes.EKeyRightArrow:
pics[ip].showed=False
if ip >= len(pics)-1:
ip=0
else:
ip=ip+1
pics[ip].showed=True
elif ev == key_codes.EKeyDownArrow:
pass
elif ev == key_codes.EKeyLeftArrow:
pics[ip].showed=False
if ip <= 0:
ip=len(pics)-1
else:
ip=ip-1
pics[ip].showed=True
handle_redraw(None)
def quit():
app_lock.signal()
################# M a i n ################
pics=None
fullsize=True
canvas = appuifw.Canvas(redraw_callback = handle_redraw,\
event_callback = handle_event)
appuifw.app.body = canvas
appuifw.app.screen = "full"
appuifw.app.exit_key_handler = quit
wb, hb = canvas.size
wb=wb*1.; hb=hb*1. # we need the size as floats
canvas.clear()
picfiles=[
"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120704.jpg"
# ,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120705.jpg"
,"E:\\HPS\\Html\\MySites\\Eva20Geburtstag\\FOTOS\\JAN22_12.JPG"
,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120706.jpg"
,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120707.jpg"
,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120708.jpg"
,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120709.jpg"
,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120710.jpg"
# ,"E:\\Images\\200911\\200911A0\\AbsolviaTrauerkneip20091120711.jpg"
]
pics=[]
for ip in picfiles:
pics.append(hpspic(ip,handle_redraw))
pics[0].showed=True
for ip in pics:
ip.load()
ip=0
#If ao_sleep active, callback func in pics[ip] can't call handle_redraw:
#e32.ao_sleep(5)
pics[ip].showed=True
app_lock = e32.Ao_lock()
app_lock.wait()
That's it.
Ciao
Peter