def touch_moved(self, data):
if self.dragging_waypoint:
self.w.center = data.location
return
if self.flood_filling:
if Vector(data.location).distance_to(self.touch_start) < 10:
return
else:
self.flood_fill(self.control.edit_menu['flood_fill'])
(w, h) = self.img.size
with ui.ImageContext(w,h) as ctx:
self.img.draw()
blend_mode = ui.BLEND_CLEAR if self.digging else ui.BLEND_NORMAL
ui.set_blend_mode(blend_mode)
ui.set_color('black')
(x, y) = data.location #* self.multiplier
(px, py) = data.prev_location #* self.multiplier
path = ui.Path()
path.move_to(px, py)
path.line_to(x, y)
path.line_width = 30 #* self.multiplier #if self.digging else 1
path.line_cap_style = ui.LINE_CAP_ROUND
path.stroke()
self.img = ctx.get_image()
#self.set_needs_display()
python类ImageContext()的实例源码
def create_zoom_frame(self):
zoomWidth = self.width / self.zoomLevels[self.zoomCurrent]
zoomHeight = self.height / self.zoomLevels[self.zoomCurrent]
# create an movable image showing the zoom area
with ui.ImageContext(320,200) as ctx:
ui.set_color('black')
line_inside = ui.Path.rect(2,2,316,196)
line_inside.line_width = 4
line_inside.stroke()
ui.set_color('white')
line_outside = ui.Path.rect(0,0,320,200)
line_outside.line_width = 4
line_outside.stroke()
zoomSquare = ctx.get_image()
zoom_frame = ui.ImageView(hidden=True)
zoom_frame.bounds = (0,0,zoomWidth,zoomHeight)
zoom_frame.center = (self.width/2, self.height/2)
zoom_frame.image = zoomSquare
self.add_subview(zoom_frame)
return zoom_frame
def redraw_canvas(self, updategrid=False):
# Gets the pixels covered by the current zoom level
zoomPixels = self.position_pixels()
# Redraw view
self.image_view.image = self.create_new_image()
with ui.ImageContext(self.width, self.height) as ctx:
for i in zoomPixels:
p = self.pixels[i]
ui.set_color(p.color)
pixel_path = ui.Path.rect(p.rect[0],p.rect[1],p.rect[2],p.rect[3])
pixel_path.fill()
pixel_path.line_width = 0.5
pixel_path.stroke()
self.image_view.image = ctx.get_image()
## Todo: insert drawing of preview window:
# Redraw grid
if updategrid == True:
self.grid_layout.image = self.draw_grid_image()
self.grid_layout.alpha = self.gridOpacity
if self.color_check.hidden is False:
self.character_colorcheck()
return True
# Flip colors
def draw_single_pixel(self, pixel):
if pixel.color != self.current_color:
if self.checkDither(pixel.position):
self.store_undo_stroke(pixel.index)
pixel.color = self.current_color
#self.pixel_path.append(pixel)
old_img = self.image_view.image
path = ui.Path.rect(*pixel.rect)
with ui.ImageContext(self.width, self.height) as ctx:
if old_img:
old_img.draw()
ui.set_color(self.current_color)
pixel_path = ui.Path.rect(*pixel.rect)
pixel_path.line_width = 0.5
pixel_path.fill()
pixel_path.stroke()
self.set_image(ctx.get_image())
def load_actual(self, burn_waypoints_in=False):
# Clear old waypoints
for wp in self.edit_view.waypoints:
self.edit_view.remove_subview(wp)
self.edit_view.waypoints = []
# Load image
img_filename = self.filename
iv = ui.ImageView(frame=self.bg.bounds)
iv.image = ui.Image(img_filename)
self.edit_view.img = snapshot(iv)
self.multiplier = self.edit_view.img.size[1]/self.edit_view.height
# Load settings
json_filename = img_filename[:-3]+'json'
if os.path.exists(json_filename):
with open(json_filename) as fp:
settings = json.load(fp)
if isinstance(settings, dict):
locations = settings['waypoint_locations']
self.bg.image = ui.Image.named(settings['bg_filename'])
self.edit_view.bg_filename = settings['bg_filename']
else:
locations = settings
self.bg.image = ui.Image.named('backgrounds/caves.jpg')
self.edit_view.bg_filename = None
for loc in locations:
wp = self.edit_view.add_waypoint()
wp.center = loc
if burn_waypoints_in:
with ui.ImageContext(self.edit_view.width, self.edit_view.height) as ctx:
self.edit_view.img.draw()
ui.set_blend_mode(ui.BLEND_CLEAR)
ui.set_color('black')
for wp in self.edit_view.waypoints:
(x,y) = wp.center
path = ui.Path.oval(x-15, y-15, 30, 30)
path.fill()
self.edit_view.img = ctx.get_image()
def fill(self):
self.history = []
self.future = []
with ui.ImageContext(self.width, self.height) as ctx:
ui.set_color('black')
ui.fill_rect(0, 0, self.width, self.height)
# iv = ui.ImageView(frame=self.bounds)
# iv.image = ui.Image('playfields/origami.png')
#
# img = snapshot(iv)
# blend_mode = ui.B
# ui.set_blend_mode(blend_mode)
#iv.image.draw()
# img.draw()
self.img = ctx.get_image()
def snapshot(view):
with ui.ImageContext(view.width, view.height) as ctx:
view.draw_snapshot()
return ctx.get_image()
def get_path_image(path):
""" Get an image of a path """
bounds = path.bounds
with ui.ImageContext(bounds.max_x, bounds.max_y) as ctx:
path.fill()
return ctx.get_image()
def init_pixel_grid(self):
s = self.width/self.row if self.row > self.column else self.height/self.column
with ui.ImageContext(*self.frame[2:]) as ctx:
for y in xrange(self.column):
for x in xrange(self.row):
# Fills image with pixels
# Changing this changes the pixel aspect
pixel = Pixel(x*s*2, y*s, s*2, s)
pixel.index = len(self.pixels)
pixel.position = (x,y)
self.pixels.append(pixel) #Adds this pixel to the pixels list
return ctx.get_image()
# Draw the pixel and character grid
# This function is pretty slow. Find a way to speed it up.
def create_new_image(self):
path = ui.Path.rect(*self.bounds)
with ui.ImageContext(self.width, self.height) as ctx:
ui.set_color((0, 0, 0, 0))
path.fill()
return ctx.get_image()
def preview_init(self):
path = ui.Path.rect(0, 0, Settings.width, Settings.height)
with ui.ImageContext(Settings.width, Settings.height) as ctx:
ui.set_color((0, 0, 0, 1))
path.fill()
self.superview['preview'].image = ctx.get_image()
return True
def preview_drawPixels(self):
zoomPixels = self.position_pixels()
old_img = self.unfilteredPreview
with ui.ImageContext(Settings.width, Settings.height) as ctx:
old_img.draw(0,0,Settings.width, Settings.height)
for i in zoomPixels:
p = self.pixels[i]
ui.set_color(p.color)
pixel_path = ui.Path.rect(p.position[0]*Settings.pixelSize,p.position[1],1*Settings.pixelSize,2)
pixel_path.line_width = 0.5
pixel_path.fill()
#pixel_path.stroke()
#self.superview['preview'].image = ctx.get_image()
self.preview_putimg(ctx.get_image())
return True
def draw_index_array(self, img, indexArray, drawColor=False, noCheck=False):
with ui.ImageContext(self.width, self.height) as ctx:
img.draw()
for i in indexArray:
# Drawing negative indices will mess up the image, so only indices from 0 and up
if i >= 0:
# Skip checks and undos and just draw the pixels
if noCheck==True:
p = self.pixels[i]
if drawColor != False:
p.color = drawColor
ui.set_color(p.color)
pixel_path = ui.Path.rect(p.rect[0],p.rect[1],p.rect[2],p.rect[3])
pixel_path.line_width = 0.0
pixel_path.fill()
pixel_path.stroke()
else:
if self.pixels[i].color != self.current_color:
if self.checkDither(self.pixels[i].position):
self.store_undo_stroke(i)
p = self.pixels[i]
if drawColor != False:
p.color = drawColor
ui.set_color(p.color)
# Path.rect(x, y, width, height)
pixel_path = ui.Path.rect(p.rect[0],p.rect[1],p.rect[2],p.rect[3])
pixel_path.line_width = 0.0
pixel_path.fill()
pixel_path.stroke()
img = ctx.get_image()
return img
# Main pixel action function!
# Called by 'touch_began', touch_moved and touch_ended
def get_histogram(img):
if not img.mode.startswith('RGB'):
img = img.convert('RGB')
hist = img.histogram()
max_h = float(max(hist))
height = 180
with ui.ImageContext(430, height) as ctx:
a = 1
rgb = [(1, 0, 0, a), (0, 1, 0, a), (0, 0, 1, a)]
for i, color in enumerate(rgb):
ui.set_color(color)
for j, count in enumerate(hist[i*256:i*256+256]):
bar_height = count / max_h * (height - 5)
ui.fill_rect(2*j, height-bar_height, 2, bar_height)
return ctx.get_image()
def draw_grid_image(self):
(startPos, endPos) = self.get_current_region()
yPixelScale = self.width/(endPos[0]-startPos[0]+1)/Settings.pixelSize #self.height/Settings.height
xPixelScale = yPixelScale*2
charSize = Settings.charSize
charScale = yPixelScale*charSize
xRangeStart = int(startPos[0]/charSize*charSize)
pixelGrid = ui.Path.rect(0, 0, *self.frame[2:])
characterGrid = ui.Path.rect(0, 0, *self.frame[2:])
charDrawColor = (1,1,1,0.5) if self.darkGrid == False else (0,0,0,0.5)
lineDrawColor = (0.5,0.5,0.5,0.5) if self.darkGrid == False else (0.25,0.25,0.25,0.5)
with ui.ImageContext(*self.frame[2:]) as ctx:
# Fills entire grid with empty color
ui.set_color((0, 0, 0, 0))
#pixelGrid.fill()
pixelGrid.line_width = 1
# Horizontal gridlines
yEnd = 200 * yPixelScale
for x in xrange(startPos[0]+1, endPos[0]+1):
xPos = (x-startPos[0]) * xPixelScale
if x%4 != 0:
pixelGrid.move_to(xPos,0)
pixelGrid.line_to(xPos,yEnd)
else:
characterGrid.move_to(xPos,0)
characterGrid.line_to(xPos,yEnd)
# Vertical gridlines
xEnd = 160 * xPixelScale
for y in xrange(startPos[1]+1, endPos[1]+1):
yPos = (y-startPos[1]) * yPixelScale
if y%8 != 0:
pixelGrid.move_to(0, yPos)
pixelGrid.line_to(xEnd, yPos)
else:
characterGrid.move_to(0, yPos)
characterGrid.line_to(xEnd, yPos)
ui.set_color(lineDrawColor)
pixelGrid.stroke()
ui.set_color(charDrawColor)
characterGrid.stroke()
return ctx.get_image()
def __init__(self, width, height):
self.frame = (0,0,width,height)
self.iwidth = 200.0
self.iheight = 200.0
framesize = 10
iw = self.iwidth - 2 * framesize
ih = self.iheight - 2 * framesize
ratio = ih / iw
self.img = []
self.imgcount = min(photos.get_count(), 100)
console.hud_alert('Please wait while {} photos are loading...'.format(self.imgcount))
for i in xrange(self.imgcount):
s = photos.get_metadata(i)
if s['filename'][-3:] == 'MOV': #skip movies
self.img.append(None)
continue
img = ui.Image.from_data(photos.get_image(i,raw_data=True))
w, h = img.size
rat = h / w
x_ratio = 1.0
y_ratio = 1.0
x = framesize
y = framesize
if ratio < 1: #landscape canvas
if rat <= ratio: #full width
y = ((ih - iw * rat) / 2) + framesize
y_ratio = iw * rat / ih
else: #full height
x = ((iw - ih / rat) / 2) + framesize
x_ratio = ih / rat / iw
elif ratio > 1: #portrait canvas
if rat > ratio: #full height
x = ((iw - ih / rat) / 2) + framesize
x_ratio = ih / rat / iw
else: #full width
y = ((ih - iw * rat) / 2) + framesize
y_ratio = iw * rat / ih
else: #cubic canvas
if rat < 1: #full width
y = ((ih - iw * rat) / 2) + framesize
y_ratio = iw * rat / ih
elif rat > 1: #full height
x = ((iw - ih / rat) / 2) + framesize
x_ratio = ih / rat / iw
else: #cubic
pass #x_ratio = y_ratio = 1.0
with ui.ImageContext(self.iwidth, self.iheight) as ctx:
img.draw(x,y,iw * x_ratio,ih * y_ratio)
self.img.append(ctx.get_image())