def merge_overlay(self, overlay): self.open() overlay.open() background_image = Image(self.image) # remove any transparent areas around the logo overlay_image = Image( Geometry(overlay.image.size().width() + 2, overlay.image.size().height() + 2), 'transparent') overlay_image.composite(overlay.image, GravityType.CenterGravity, CompositeOperator.OverCompositeOp) overlay_image.trim() border_width = int( math.ceil(background_image.size().width() * PIconBackground.BORDER_RATIO)) overlay_image.zoom( Geometry(background_image.size().width() - (border_width * 2), background_image.size().height() - (border_width * 2))) # we need to calculate exact position since we get 1-pixel error # if the height of the logo is odd and using GravityType.CenterGravity if overlay_image.size().width() + ( 2 * border_width) == background_image.size().width(): x = border_width y = int( math.ceil((background_image.size().height() / 2.0) - (overlay_image.size().height() / 2.0))) else: x = int( math.ceil((background_image.size().width() / 2.0) - (overlay_image.size().width() / 2.0))) y = border_width background_image.composite(overlay_image, x, y, CompositeOperator.OverCompositeOp) return PIcon(background_image)
def _watermark(self, image, watermark_path, opacity, size, position_str): with open(watermark_path, 'rb') as watermark_file: watermark = self.get_image(watermark_file) image_size = self.get_image_size(image) layer = Image(Geometry(image_size[0], image_size[1]), 'transparent') if opacity < 1: self._reduce_opacity(watermark, opacity) if not size: mark_size = self.get_image_size(watermark) else: mark_size = tuple( self._get_new_watermark_size(size, self.get_image_size(watermark))) options = { 'crop': 'center', 'upscale': mark_size > self.get_image_size(watermark) } watermark = self.scale(watermark, mark_size, options) watermark = self.crop(watermark, mark_size, options) if position_str == 'tile': for x_pos in range(0, image_size[0], mark_size[0]): for y_pos in range(0, image_size[1], mark_size[1]): layer.composite(watermark, x_pos, y_pos, CoOp.OverCompositeOp) else: position = self._define_watermark_position(position_str, image_size, mark_size) layer.composite(watermark, position[0], position[1], CoOp.OverCompositeOp) image.composite(layer, 0, 0, CoOp.OverCompositeOp) return image
def _xor_composite_clip_layer(self, clips, layer_level=0): """ round two clipping. """ #skip the first clip as it doesn't need anything taken away from it. this_clip = GMImage(os.path.join(self.clips_dir, 'clip-%s.png' % clips[0])) this_clip.write(os.path.join(self.clips_dir, "clip-co-%s.png" % clips[0])) #self.masks.append(os.path.join(self.clips_dir, 'clip-co-%s.png' % #clips[0])) clip_i = 0 for clip_id in clips[1:]: previous_clip = GMImage(os.path.join(self.clips_dir, 'clip-%s.png' % clips[clip_i])) this_clip = GMImage(os.path.join(self.clips_dir, 'clip-%s.png' % clip_id)) this_clip.composite(previous_clip, 0, 0, co.XorCompositeOp) img_file = os.path.join(self.clips_dir, "clip-co-%s.png" % clip_id) this_clip.write(img_file) clip_i = clip_i + 1 im = Image.open(img_file) if not im.getbbox(): # nothing there so delete it os.unlink(img_file)
def _xor_composite_clip_layer(self, clips, layer_level=0): """ round two clipping. """ #skip the first clip as it doesn't need anything taken away from it. this_clip = GMImage( os.path.join(self.clips_dir, 'clip-%s.png' % clips[0])) this_clip.write( os.path.join(self.clips_dir, "clip-co-%s.png" % clips[0])) #self.masks.append(os.path.join(self.clips_dir, 'clip-co-%s.png' % #clips[0])) clip_i = 0 for clip_id in clips[1:]: previous_clip = GMImage( os.path.join(self.clips_dir, 'clip-%s.png' % clips[clip_i])) this_clip = GMImage( os.path.join(self.clips_dir, 'clip-%s.png' % clip_id)) this_clip.composite(previous_clip, 0, 0, co.XorCompositeOp) img_file = os.path.join(self.clips_dir, "clip-co-%s.png" % clip_id) this_clip.write(img_file) clip_i = clip_i + 1 im = Image.open(img_file) if not im.getbbox(): # nothing there so delete it os.unlink(img_file)
def _watermark(self, image, watermark_path, opacity, size, position_str): with open(watermark_path, "rb") as watermark_file: watermark = self.get_image(watermark_file) image_size = self.get_image_size(image) layer = Image(Geometry(image_size[0], image_size[1]), "transparent") if opacity < 1: self._reduce_opacity(watermark, opacity) if not size: mark_size = self.get_image_size(watermark) else: mark_size = tuple( self._get_new_watermark_size(size, self.get_image_size(watermark)) ) options = { "crop": "center", "upscale": mark_size > self.get_image_size(watermark), } watermark = self.scale(watermark, mark_size, options) watermark = self.crop(watermark, mark_size, options) if position_str == "tile": for x_pos in range(0, image_size[0], mark_size[0]): for y_pos in range(0, image_size[1], mark_size[1]): layer.composite(watermark, x_pos, y_pos, CoOp.OverCompositeOp) else: position = self._define_watermark_position( position_str, image_size, mark_size ) layer.composite(watermark, position[0], position[1], CoOp.OverCompositeOp) image.composite(layer, 0, 0, CoOp.OverCompositeOp) return image
def resize9(srcFile="", destFile="", w=200, h=200, color="", crop=False, align="center"): img = Image(srcFile) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #目标图与源图的宽比例 wScale = float(w) / float(sw) #目标图与源图的高比例 hScale = float(h) / float(sh) if (w > sw or h > sh): if (wScale == hScale): tw = w th = h elif (wScale < hScale): th = h tw = sw * wScale else: tw = w th = sh * hScale elif (w < sw or h < sh): if (wScale == hScale): tw = w th = h elif (wScale < hScale): th = h tw = sw * wScale else: tw = w th = sh * hScale else: tw = sw th = sh img.scale("%dx%d" % (tw, th)) backImg = Image(Geometry(w, h), 'white') backImg.composite(img, GravityType.CenterGravity, co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True"
def buildImage(self): #first build the image, we need to know how big it is with open(self.dataBase + "base.json", "r") as f: base = json.loads(f.read()) self.totalWidth = base['width'] self.totalHeight = base['height'] print ("Creating large base image", int(self.totalWidth), 'x',int(self.totalHeight) ) im = Image(Geometry(int(self.totalWidth), int(self.totalHeight)), Color("black")) #throw a logo onnn #layer = Image('logo.png') #im.composite(layer, 0, 0, co.OverCompositeOp) for file in os.listdir(self.dataNodes): if file.endswith('.json'): with open(self.dataNodes + file, "r") as f: nodes = json.loads(f.read()) print ("Building Image Nodes", self.dataNodes + file, len(nodes)) self.buildCounterNodeTotal = len(nodes) self.buildCounterNode = 0 for node in nodes: self.buildCounterNode+=1 print (self.buildCounterNode / self.buildCounterNodeTotal * 100)," percent complete of this batch \r", layer = Image(self.dataCircles + str(node['id']) +'.png') cords = self.convertCoordinates(node['posX'],node['posY']) im.composite(layer, int(cords[0]), int(cords[1]), co.OverCompositeOp) print ("") print ("Writing large file out") im.write('base.png')
def resize9( srcFile="", destFile="", w=200,h=200, color="", crop=False, align="center" ): img = Image(srcFile) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #目标图与源图的宽比例 wScale = float(w)/float(sw) #目标图与源图的高比例 hScale = float(h)/float(sh) if ( w > sw or h > sh ): if (wScale == hScale ): tw = w th = h elif ( wScale < hScale ): th = h tw = sw*wScale else: tw = w th = sh*hScale elif( w<sw or h < sh ): if (wScale == hScale ): tw = w th = h elif ( wScale < hScale ): th = h tw = sw*wScale else: tw = w th = sh*hScale else: tw = sw th = sh img.scale("%dx%d"%(tw,th)) backImg = Image(Geometry(w,h), 'white' ) backImg.composite(img,GravityType.CenterGravity,co.OverCompositeOp ) backImg.profile("*",Blob()) backImg.write(destFile) return "True"
def _in_composite(self, previous_clips, clips): for prev_clip_id in previous_clips: for this_clip_id in clips: previous_clip = GMImage(os.path.join(self.clips_dir, 'clip-co-%s.png' % prev_clip_id)) this_clip = GMImage(os.path.join(self.clips_dir, 'clip-co-%s.png' % this_clip_id)) this_clip.composite(previous_clip, 0, 0, co.InCompositeOp) img_file = os.path.join(self.clips_dir, "clip-in-%s-%s.png" % (prev_clip_id, this_clip_id)) this_clip.write(img_file) im = Image.open(img_file) if not im.getbbox(): # nothing there so delete it os.unlink(img_file) else: self.masks.append(img_file)
def _composite(self, mask, pic, i=0): """ composite of mask and pic. also trims it and renames with offset. """ base = GMImage(pic) layer = GMImage(mask) base.composite(layer, 0, 0, co.CopyOpacityCompositeOp) finished_clip_filename = os.path.join(self.target_directory, self.junk_dir, "%s-%s.png" % (os.path.basename(pic), os.path.basename(mask))) base.write(finished_clip_filename) box = self._trim(finished_clip_filename, os.path.join(self.target_directory, self.raster_dir, "%i.png" % i)) self._potrace(mask, i=i, trimmedpng=os.path.join(self.target_directory, self.raster_dir,"%i.png" % i)) self.pieces[i] = box
def bobross(self,imgStr): print "bobross()" bob=Image('bob-transparent-canvas.png') bob.matte(True) #print "1" img=Image(imgStr) #print "2" newsize=Geometry(200,343) newsize.aspect(True) img.scale(newsize) #print "3" img=self.watercolor(img) #print "4" result=Image(bob.size(),'white') result.composite(img,392,22,CompositeOperator.OverCompositeOp) result.composite(bob,0,0,CompositeOperator.OverCompositeOp) return result
def _watermark(self, image, watermark_path, opacity, size, position_str): watermark = self.get_image(open(watermark_path)) image_size = self.get_image_size(image) layer = Image(Geometry(image_size[0], image_size[1]), 'transparent') if opacity < 1: self._reduce_opacity(watermark, opacity) if not size: mark_size = self.get_image_size(watermark) else: mark_size = self._get_new_watermark_size(size, self.get_image_size(watermark)) options = {'crop': 'center', 'upscale': False} watermark = self.scale(watermark, mark_size, options) watermark = self.crop(watermark, mark_size, options) position = self._define_watermark_position(position_str, image_size, mark_size) layer.composite(watermark, position[0], position[1], CoOp.OverCompositeOp) image.composite(layer, 0, 0, CoOp.OverCompositeOp) return image
def watercolor(self,imgStr): img=Image(imgStr) img.blur(2,2) img.oilPaint(5) img.enhance() img.sharpen() pink=Color(250,218,221,75) toplayer=Image(img.size(),pink) toplayer.matte(True) img.matte(True) img.composite(toplayer,0,0,CompositeOperator.CopyOpacityCompositeOp) img.blur(2,2) #img.write('watercolor-output.png') return img
def merge_overlay(self, overlay): self.open() overlay.open() background_image = Image(self.image) # remove any transparent areas around the logo overlay_image = Image(Geometry(overlay.image.size().width() + 2, overlay.image.size().height() + 2), 'transparent') overlay_image.composite(overlay.image, GravityType.CenterGravity, CompositeOperator.OverCompositeOp) overlay_image.trim() border_width = int(math.ceil(background_image.size().width() * PIconBackground.BORDER_RATIO)) overlay_image.zoom(Geometry(background_image.size().width() - (border_width * 2), background_image.size().height() - (border_width * 2))) # we need to calculate exact position since we get 1-pixel error # if the height of the logo is odd and using GravityType.CenterGravity if overlay_image.size().width() + (2 * border_width) == background_image.size().width(): x = border_width y = int(math.ceil((background_image.size().height() / 2.0) - (overlay_image.size().height() / 2.0))) else: x = int(math.ceil((background_image.size().width() / 2.0) - (overlay_image.size().width() / 2.0))) y = border_width background_image.composite(overlay_image, x, y, CompositeOperator.OverCompositeOp) return PIcon(background_image)
def _watermark(self, image, watermark_path, opacity, size, position_str): watermark = self.get_image(open(watermark_path)) image_size = self.get_image_size(image) layer = Image(Geometry(image_size[0], image_size[1]), 'transparent') if opacity < 1: self._reduce_opacity(watermark, opacity) if not size: mark_size = self.get_image_size(watermark) else: mark_size = self._get_new_watermark_size( size, self.get_image_size(watermark)) options = {'crop': 'center', 'upscale': False} watermark = self.scale(watermark, mark_size, options) watermark = self.crop(watermark, mark_size, options) position = self._define_watermark_position(position_str, image_size, mark_size) layer.composite(watermark, position[0], position[1], CoOp.OverCompositeOp) image.composite(layer, 0, 0, CoOp.OverCompositeOp) return image
def _in_composite(self, previous_clips, clips): for prev_clip_id in previous_clips: for this_clip_id in clips: previous_clip = GMImage( os.path.join(self.clips_dir, 'clip-co-%s.png' % prev_clip_id)) this_clip = GMImage( os.path.join(self.clips_dir, 'clip-co-%s.png' % this_clip_id)) this_clip.composite(previous_clip, 0, 0, co.InCompositeOp) img_file = os.path.join( self.clips_dir, "clip-in-%s-%s.png" % (prev_clip_id, this_clip_id)) this_clip.write(img_file) im = Image.open(img_file) if not im.getbbox(): # nothing there so delete it os.unlink(img_file) else: self.masks.append(img_file)
def resize8(srcFile="", destFile="", w=200, h=200): img = Image(srcFile) #.def("extent", (void (Magick::Image::*)(const Magick::Geometry&, const Magick::Color&, const Magick::GravityType))&Magick::Image::extent) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #若目标图的宽或高都比源图大则不处理 if (sw <= w and sh <= h): backImg = Image(Geometry(w, h), 'white') backImg.composite(img, GravityType.CenterGravity, co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" #目标的宽或高都比源图的小则进行裁剪 elif (sw > w and sh > h): #源图的宽高比 sratio = float(sw) / float(sh) rratio = float(w) / float(h) #若源图宽高比大于目标图的宽高比的话,则就高缩放,从0,0位置裁前源图宽 #print sratio,rratio if (sratio > rratio): hscale = float(h) / float(sh) rw = int(sw * hscale) rh = int(sh * hscale) else: wscale = float(w) / float(sw) rw = int(sw * wscale) rh = int(sh * wscale) linePos = int((rw - w) / 2) colPos = int((rh - h) / 2) img.scale("%dx%d" % (rw, rh)) img.crop(Geometry(w, h, linePos, colPos)) img.profile("*", Blob()) img.write(destFile) return "True" elif (sw > w): backImg = Image(Geometry(w, h), 'white') img.crop(Geometry(w, sh, int((sw - w) / 2))) backImg.composite(img, GravityType.CenterGravity, co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" elif (sh > h): backImg = Image(Geometry(w, h), 'white') img.crop(Geometry(sw, h, 0, int((sh - h) / 2))) backImg.composite(img, GravityType.CenterGravity, co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" return "True"
def _composite(self, mask, pic, i=0): """ composite of mask and pic. also trims it and renames with offset. """ base = GMImage(pic) layer = GMImage(mask) base.composite(layer, 0, 0, co.CopyOpacityCompositeOp) finished_clip_filename = os.path.join( self.target_directory, self.junk_dir, "%s-%s.png" % (os.path.basename(pic), os.path.basename(mask))) base.write(finished_clip_filename) box = self._trim( finished_clip_filename, os.path.join(self.target_directory, self.raster_dir, "%i.png" % i)) self._potrace(mask, i=i, trimmedpng=os.path.join(self.target_directory, self.raster_dir, "%i.png" % i)) self.pieces[i] = box
def bobross(self,imgStr): bob=Image('bob-transparent-canvas.png') bob.matte(True) img=self.watercolor(imgStr) #img.matte(True) newsize=Geometry(210,380) newsize.aspect(True) img.scale(newsize) #img.oilPaint(3) #img.enhance() #img.sharpen() #img.blur(2,2) #img.shear(-25,-15) result=Image(bob.size(),'white') result.composite(img,390,20,CompositeOperator.OverCompositeOp) result.composite(bob,0,0,CompositeOperator.OverCompositeOp) #img.debug(True) #bob.composite(img,390,20,CompositeOperator.OverCompositeOp) return result
def resize8( srcFile="", destFile="", w=200,h=200 ): img = Image(srcFile) #.def("extent", (void (Magick::Image::*)(const Magick::Geometry&, const Magick::Color&, const Magick::GravityType))&Magick::Image::extent) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #若目标图的宽或高都比源图大则不处理 if ( sw <= w and sh <= h ): backImg = Image(Geometry(w,h), 'white' ) backImg.composite(img, GravityType.CenterGravity, co.OverCompositeOp) backImg.profile("*",Blob()) backImg.write(destFile) return "True" #目标的宽或高都比源图的小则进行裁剪 elif ( sw > w and sh > h ): #源图的宽高比 sratio = float(sw)/float(sh) rratio = float(w)/float(h) #若源图宽高比大于目标图的宽高比的话,则就高缩放,从0,0位置裁前源图宽 #print sratio,rratio if ( sratio > rratio ): hscale = float(h)/float(sh) rw = int(sw*hscale) rh = int(sh*hscale) else: wscale = float(w)/float(sw) rw = int(sw*wscale) rh = int(sh*wscale) linePos = int( (rw-w)/2) colPos = int( (rh-h)/2) img.scale("%dx%d"%(rw,rh)) img.crop(Geometry(w,h,linePos,colPos)) img.profile("*",Blob()) img.write(destFile) return "True" elif ( sw > w ): backImg = Image(Geometry(w,h), 'white' ) img.crop(Geometry(w,sh,int((sw-w)/2))) backImg.composite(img,GravityType.CenterGravity,co.OverCompositeOp ) backImg.profile("*",Blob()) backImg.write(destFile) return "True" elif ( sh > h ): backImg = Image(Geometry(w,h), 'white' ) img.crop( Geometry(sw,h,0,int((sh-h)/2) ) ) backImg.composite(img, GravityType.CenterGravity,co.OverCompositeOp ) backImg.profile("*",Blob()) backImg.write(destFile) return "True" return "True"
def resize7( srcFile="", destFile="", w=200,h=200 ): img = Image(srcFile) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #若目标图的宽或高都比源图大则不处理 if ( sw <= w and sh <= h ): backImg = Image(Geometry(w,h), 'white' ) backImg.composite(img, Geometry( sw, sh, 0, 0 ), co.OverCompositeOp) backImg.profile("*",Blob()) backImg.write(destFile) return "True" #目标的宽或高都比源图的小则进行裁剪 elif ( sw > w and sh > h ): #源图的宽高比 sratio = float(sw)/float(sh) rratio = float(w)/float(h) #若源图宽高比大于目标图的宽高比的话,则就高缩放,从0,0位置裁前源图宽 #print sratio,rratio if ( sratio > rratio ): hscale = float(h)/float(sh) rw = int(sw*hscale) rh = int(sh*hscale) else: wscale = float(w)/float(sw) rw = int(sw*wscale) rh = int(sh*wscale) img.scale("%dx%d"%(rw,rh)) img.crop(Geometry(w,h,0,0)) img.profile("*",Blob()) img.write(destFile) return "True" elif ( sw > w ): backImg = Image(Geometry(w,h), 'white' ) img.crop(Geometry(w,sh)) backImg.composite(img,Geometry(w,h,0,0),co.OverCompositeOp ) backImg.profile("*",Blob()) backImg.write(destFile) return "True" elif ( sh > h ): backImg = Image(Geometry(w,h), 'white' ) img.crop( Geometry(sw,h) ) backImg.composite(img, Geometry(w,h,0,0),co.OverCompositeOp ) backImg.profile("*",Blob()) backImg.write(destFile) return "True" return "True"
def resize7(srcFile="", destFile="", w=200, h=200): img = Image(srcFile) #白色背景图 backImg = None #sw源图宽度 sw = img.columns() #sh源图高度 sh = img.rows() #若目标图的宽或高都比源图大则不处理 if (sw <= w and sh <= h): backImg = Image(Geometry(w, h), 'white') backImg.composite(img, Geometry(sw, sh, 0, 0), co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" #目标的宽或高都比源图的小则进行裁剪 elif (sw > w and sh > h): #源图的宽高比 sratio = float(sw) / float(sh) rratio = float(w) / float(h) #若源图宽高比大于目标图的宽高比的话,则就高缩放,从0,0位置裁前源图宽 #print sratio,rratio if (sratio > rratio): hscale = float(h) / float(sh) rw = int(sw * hscale) rh = int(sh * hscale) else: wscale = float(w) / float(sw) rw = int(sw * wscale) rh = int(sh * wscale) img.scale("%dx%d" % (rw, rh)) img.crop(Geometry(w, h, 0, 0)) img.profile("*", Blob()) img.write(destFile) return "True" elif (sw > w): backImg = Image(Geometry(w, h), 'white') img.crop(Geometry(w, sh)) backImg.composite(img, Geometry(w, h, 0, 0), co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" elif (sh > h): backImg = Image(Geometry(w, h), 'white') img.crop(Geometry(sw, h)) backImg.composite(img, Geometry(w, h, 0, 0), co.OverCompositeOp) backImg.profile("*", Blob()) backImg.write(destFile) return "True" return "True"
def extract_substack( job ): """ Extracts a sub-stack as specified in the passed job. A list of pgmagick images is returned -- one for each slice, starting on top. """ # Calculate the slice numbers and pixel positions # bounded to the stack data. px_x_min = to_x_index(job.x_min, job) px_x_max = to_x_index(job.x_max, job) px_y_min = to_y_index(job.y_min, job) px_y_max = to_y_index(job.y_max, job) px_z_min = to_z_index(job.z_min, job) px_z_max = to_z_index(job.z_max, job) # Because it might be that the cropping goes over the # stack bounds, we need to calculate the unbounded height, # with and an offset. px_x_min_nobound = to_x_index(job.x_min, job, False) px_x_max_nobound = to_x_index(job.x_max, job, False) px_y_min_nobound = to_y_index(job.y_min, job, False) px_y_max_nobound = to_y_index(job.y_max, job, False) width = px_x_max_nobound - px_x_min_nobound height = px_y_max_nobound - px_y_min_nobound px_x_offset = abs(px_x_min_nobound) if px_x_min_nobound < 0 else 0 px_y_offset = abs(px_y_min_nobound) if px_y_min_nobound < 0 else 0 # The images are generated per slice, so most of the following # calculations refer to 2d images. # Each stack to export is treated as a seperate channel. The order # of the exported dimensions is XYCZ. This means all the channels of # one slice are exported, then the next slice follows, etc. cropped_stack = [] # Iterate over all slices for z in range( px_z_min, px_z_max + 1): for stack in job.stacks: # Get indices for bounding tiles (0 indexed) tile_x_min = int(px_x_min / tile_size) tile_x_max = int(px_x_max / tile_size) tile_y_min = int(px_y_min / tile_size) tile_y_max = int(px_y_max / tile_size) # Get the number of needed tiles for each direction num_x_tiles = tile_x_max - tile_x_min + 1 num_y_tiles = tile_y_max - tile_y_min + 1 # Associate image parts with all tiles image_parts = [] x_dst = px_x_offset for nx, x in enumerate( range(tile_x_min, tile_x_max + 1) ): # The min x,y for the image part in the current tile are 0 # for all tiles except the first one. cur_px_x_min = 0 if nx > 0 else px_x_min - x * tile_size # The max x,y for the image part of current tile are the tile # size minus one except for the last one. cur_px_x_max = tile_size - 1 if nx < (num_x_tiles - 1) else px_x_max - x * tile_size # Reset y destination component y_dst = px_y_offset for ny, y in enumerate( range(tile_y_min, tile_y_max + 1) ): cur_px_y_min = 0 if ny > 0 else px_y_min - y * tile_size cur_px_y_max = tile_size - 1 if ny < (num_y_tiles - 1) else px_y_max - y * tile_size # Create an image part definition path = get_tile_path(job, stack, [x, y, z]) try: part = ImagePart(path, cur_px_x_min, cur_px_x_max, cur_px_y_min, cur_px_y_max, x_dst, y_dst) image_parts.append( part ) except: # ignore failed slices pass # Update y component of destination postition y_dst += cur_px_y_max - cur_px_y_min # Update x component of destination postition x_dst += cur_px_x_max - cur_px_x_min # Create a result image slice, painted black cropped_slice = Image( Geometry( width, height ), Color("black") ) # write out the image parts for ip in image_parts: # Get (correcly cropped) image image = ip.get_image() # Draw the image onto result image cropped_slice.composite( image, ip.x_dst, ip.y_dst, co.OverCompositeOp ) # Delete tile image - it's not needed anymore del image # Add the imag to the cropped stack cropped_stack.append( cropped_slice ) return cropped_stack
def export_area(x1, y1, z1, x2, y2, z2, chunks, assets, data): if x1 > x2: x1, x2 = x2, x1 if y1 > y2: y1, y2 = y2, y1 if x1 > x2: z1, z2 = z2, z1 cache = {} unknow = Image(Geometry(16, 16), "fuchsia") hardcoded = { 'minecraft:air': Color('white'), 'minecraft:cave_air': Color('black'), 'minecraft:water': Color('blue'), # TODO use 'block/water_still' with #0080ff tint 'minecraft:lava': 'block/lava_still', } for x in hardcoded: if isinstance(hardcoded[x], Color): hardcoded[x] = Image(Geometry(16, 16), hardcoded[x]) else: hardcoded[x] = Image("%s/textures/%s.png" % (assets.directory, hardcoded[x])) hardcoded[x].crop(Geometry(16, 16)) for y in range(y2 - y1): img = Image(Geometry(16 * (x2 - x1), 16 * (z2 - z1)), 'transparent') for z in range(z2 - z1): for x in range(x2 - x1): try: i = None sid = chunks.get_block_at(x + x1, y + y1, z + z1) if sid in cache: i = cache[sid] else: bloc = data.blocks_states[sid] if bloc in hardcoded: i = hardcoded[bloc] else: prop = data.blocks_properties[sid] variant = assets.get_block_variant(bloc, prop) if 'model' in variant: faces = assets.get_faces_textures( assets.get_model(variant['model'])) if 'up' in faces: up = faces['up'] i = Image( "%s/textures/%s.png" % (assets.directory, up['texture'])) if "uv" in up: pass # TODO i.crop(Geometry(16, 16)) if "tintindex" in up: tint = '#80ff00' ti = Image(Geometry(16, 16), tint) i.composite( ti, 0, 0, CompositeOperator. MultiplyCompositeOp) if not i: i = unknow cache[sid] = i img.composite(i, x * 16, z * 16, CompositeOperator.OverCompositeOp) except Exception: continue img.write("/tmp/slice_%d.png" % (y))
def extract_substack_no_rotation(job): """ Extracts a sub-stack as specified in the passed job without respecting rotation requests. A list of pgmagick images is returned -- one for each slice, starting on top. """ # The actual bounding boxes used for creating the images of each stack # depend not only on the request, but also on the translation of the stack # wrt. the project. Therefore, a dictionary with bounding box information for # each stack is created. s_to_bb = {} for stack in job.stacks: # Retrieve translation relative to current project translation = ProjectStack.objects.get(project_id=job.project_id, stack_id=stack.id).translation x_min_t = job.x_min - translation.x x_max_t = job.x_max - translation.x y_min_t = job.y_min - translation.y y_max_t = job.y_max - translation.y z_min_t = job.z_min - translation.z z_max_t = job.z_max - translation.z # Calculate the slice numbers and pixel positions # bound to the stack data. px_x_min = to_x_index(x_min_t, job) px_x_max = to_x_index(x_max_t, job) px_y_min = to_y_index(y_min_t, job) px_y_max = to_y_index(y_max_t, job) px_z_min = to_z_index(z_min_t, job) px_z_max = to_z_index(z_max_t, job) # Because it might be that the cropping goes over the # stack bounds, we need to calculate the unbounded height, # with and an offset. px_x_min_nobound = to_x_index(x_min_t, job, False) px_x_max_nobound = to_x_index(x_max_t, job, False) px_y_min_nobound = to_y_index(y_min_t, job, False) px_y_max_nobound = to_y_index(y_max_t, job, False) width = px_x_max_nobound - px_x_min_nobound height = px_y_max_nobound - px_y_min_nobound px_x_offset = abs(px_x_min_nobound) if px_x_min_nobound < 0 else 0 px_y_offset = abs(px_y_min_nobound) if px_y_min_nobound < 0 else 0 # Create a dictionary entry with a simple object class BB: pass bb = BB() bb.px_x_min = px_x_min bb.px_x_max = px_x_max bb.px_y_min = px_y_min bb.px_y_max = px_y_max bb.px_z_min = px_z_min bb.px_z_max = px_z_max bb.px_x_offset = px_x_offset bb.px_y_offset = px_y_offset bb.width = width bb.height = height s_to_bb[stack.id] = bb # Get number of wanted slices px_z_min = to_z_index(job.z_min, job) px_z_max = to_z_index(job.z_max, job) n_slices = px_z_max + 1 - px_z_min # The images are generated per slice, so most of the following # calculations refer to 2d images. # Each stack to export is treated as a separate channel. The order # of the exported dimensions is XYCZ. This means all the channels of # one slice are exported, then the next slice follows, etc. cropped_stack = [] # Iterate over all slices for nz in range(n_slices): for stack in job.stacks: bb = s_to_bb[stack.id] # Shortcut for tile width and height tile_width = stack.tile_width tile_height = stack.tile_height # Get indices for bounding tiles (0 indexed) tile_x_min = int(bb.px_x_min / tile_width) tile_x_max = int(bb.px_x_max / tile_width) tile_y_min = int(bb.px_y_min / tile_height) tile_y_max = int(bb.px_y_max / tile_height) # Get the number of needed tiles for each direction num_x_tiles = tile_x_max - tile_x_min + 1 num_y_tiles = tile_y_max - tile_y_min + 1 # Associate image parts with all tiles image_parts = [] x_dst = bb.px_x_offset for nx, x in enumerate(range(tile_x_min, tile_x_max + 1)): # The min x,y for the image part in the current tile are 0 # for all tiles except the first one. cur_px_x_min = 0 if nx > 0 else bb.px_x_min - x * tile_width # The max x,y for the image part of current tile are the tile # size minus one except for the last one. if nx < (num_x_tiles - 1): cur_px_x_max = tile_width - 1 else: cur_px_x_max = bb.px_x_max - x * tile_width # Reset y destination component y_dst = bb.px_y_offset for ny, y in enumerate(range(tile_y_min, tile_y_max + 1)): cur_px_y_min = 0 if ny > 0 else bb.px_y_min - y * tile_height if ny < (num_y_tiles - 1): cur_px_y_max = tile_height - 1 else: cur_px_y_max = bb.px_y_max - y * tile_height # Create an image part definition z = bb.px_z_min + nz path = job.get_tile_path(stack, (x, y, z)) try: part = ImagePart(path, cur_px_x_min, cur_px_x_max, cur_px_y_min, cur_px_y_max, x_dst, y_dst) image_parts.append(part) except: # ignore failed slices pass # Update y component of destination position y_dst += cur_px_y_max - cur_px_y_min # Update x component of destination position x_dst += cur_px_x_max - cur_px_x_min # write out the image parts cropped_slice = None for ip in image_parts: # Get (correctly cropped) image image = ip.get_image() # It is unfortunately not possible to create proper composite # images based on a canvas image newly created like this: # cropped_slice = Image( Geometry(bb.width, bb.height), Color("black")) # Therefore, this workaround is used. if not cropped_slice: cropped_slice = Image(image) cropped_slice.backgroundColor("black") cropped_slice.erase() # The '!' makes sure the aspect ration is ignored cropped_slice.scale('%sx%s!' % (bb.width, bb.height)) # Draw the image onto result image cropped_slice.composite(image, ip.x_dst, ip.y_dst, co.OverCompositeOp) # Delete tile image - it's not needed anymore del image # Optionally, use only a single channel if job.single_channel: cropped_slice.channel(ChannelType.RedChannel) # Add the image to the cropped stack cropped_stack.append(cropped_slice) return cropped_stack
def extract_substack_no_rotation(job) -> List: """ Extracts a sub-stack as specified in the passed job without respecting rotation requests. A list of pgmagick images is returned -- one for each slice, starting on top. """ # The actual bounding boxes used for creating the images of each stack # depend not only on the request, but also on the translation of the stack # wrt. the project. Therefore, a dictionary with bounding box information for # each stack is created. s_to_bb = {} for stack_mirror in job.stack_mirrors: stack = stack_mirror.stack # Retrieve translation relative to current project translation = ProjectStack.objects.get(project_id=job.project_id, stack_id=stack.id).translation x_min_t = job.x_min - translation.x x_max_t = job.x_max - translation.x y_min_t = job.y_min - translation.y y_max_t = job.y_max - translation.y z_min_t = job.z_min - translation.z z_max_t = job.z_max - translation.z # Calculate the slice numbers and pixel positions # bound to the stack data. px_x_min = to_x_index(x_min_t, stack, job.zoom_level) px_x_max = to_x_index(x_max_t, stack, job.zoom_level) px_y_min = to_y_index(y_min_t, stack, job.zoom_level) px_y_max = to_y_index(y_max_t, stack, job.zoom_level) px_z_min = to_z_index(z_min_t, stack, job.zoom_level) px_z_max = to_z_index(z_max_t, stack, job.zoom_level) # Because it might be that the cropping goes over the # stack bounds, we need to calculate the unbounded height, # with and an offset. px_x_min_nobound = to_x_index(x_min_t, stack, job.zoom_level, False) px_x_max_nobound = to_x_index(x_max_t, stack, job.zoom_level, False) px_y_min_nobound = to_y_index(y_min_t, stack, job.zoom_level, False) px_y_max_nobound = to_y_index(y_max_t, stack, job.zoom_level, False) width = px_x_max_nobound - px_x_min_nobound height = px_y_max_nobound - px_y_min_nobound px_x_offset = abs(px_x_min_nobound) if px_x_min_nobound < 0 else 0 px_y_offset = abs(px_y_min_nobound) if px_y_min_nobound < 0 else 0 # Create a dictionary entry with a simple object bb = BB() bb.px_x_min = px_x_min bb.px_x_max = px_x_max bb.px_y_min = px_y_min bb.px_y_max = px_y_max bb.px_z_min = px_z_min bb.px_z_max = px_z_max bb.px_x_offset = px_x_offset bb.px_y_offset = px_y_offset bb.width = width bb.height = height s_to_bb[stack.id] = bb # Get number of wanted slices px_z_min = to_z_index(job.z_min, job.ref_stack, job.zoom_level) px_z_max = to_z_index(job.z_max, job.ref_stack, job.zoom_level) n_slices = px_z_max + 1 - px_z_min # The images are generated per slice, so most of the following # calculations refer to 2d images. # Each stack to export is treated as a separate channel. The order # of the exported dimensions is XYCZ. This means all the channels of # one slice are exported, then the next slice follows, etc. cropped_stack = [] # Accumulator for estimated result size estimated_total_size = 0 # Iterate over all slices for nz in range(n_slices): for mirror in job.stack_mirrors: stack = mirror.stack bb = s_to_bb[stack.id] # Shortcut for tile width and height tile_width = mirror.tile_width tile_height = mirror.tile_height # Get indices for bounding tiles (0 indexed) tile_x_min = int(bb.px_x_min / tile_width) tile_x_max = int(bb.px_x_max / tile_width) tile_y_min = int(bb.px_y_min / tile_height) tile_y_max = int(bb.px_y_max / tile_height) # Get the number of needed tiles for each direction num_x_tiles = tile_x_max - tile_x_min + 1 num_y_tiles = tile_y_max - tile_y_min + 1 # Associate image parts with all tiles image_parts = [] x_dst = bb.px_x_offset for nx, x in enumerate(range(tile_x_min, tile_x_max + 1)): # The min x,y for the image part in the current tile are 0 # for all tiles except the first one. cur_px_x_min = 0 if nx > 0 else bb.px_x_min - x * tile_width # The max x,y for the image part of current tile are the tile # size minus one except for the last one. if nx < (num_x_tiles - 1): cur_px_x_max = tile_width - 1 else: cur_px_x_max = bb.px_x_max - x * tile_width # Reset y destination component y_dst = bb.px_y_offset for ny, y in enumerate(range(tile_y_min, tile_y_max + 1)): cur_px_y_min = 0 if ny > 0 else bb.px_y_min - y * tile_height if ny < (num_y_tiles - 1): cur_px_y_max = tile_height - 1 else: cur_px_y_max = bb.px_y_max - y * tile_height # Create an image part definition z = bb.px_z_min + nz path = job.get_tile_path(stack, mirror, (x, y, z)) try: part = ImagePart(path, cur_px_x_min, cur_px_x_max, cur_px_y_min, cur_px_y_max, x_dst, y_dst) image_parts.append(part) except: # ignore failed slices pass # Update y component of destination position y_dst += cur_px_y_max - cur_px_y_min # Update x component of destination position x_dst += cur_px_x_max - cur_px_x_min # Write out the image parts and make sure the maximum allowed file # size isn't exceeded. cropped_slice = Image(Geometry(bb.width, bb.height), ColorRGB(0, 0, 0)) for ip in image_parts: # Get (correctly cropped) image image = ip.get_image() # Estimate total file size and abort if this exceeds the # maximum allowed file size. estimated_total_size = estimated_total_size + ip.estimated_size if estimated_total_size > settings.GENERATED_FILES_MAXIMUM_SIZE: raise ValueError("The estimated size of the requested image " "region is larger than the maximum allowed " "file size: %0.2f > %s Bytes" % \ (estimated_total_size, settings.GENERATED_FILES_MAXIMUM_SIZE)) # Draw the image onto result image cropped_slice.composite(image, ip.x_dst, ip.y_dst, co.OverCompositeOp) # Delete tile image - it's not needed anymore del image if cropped_slice: # Optionally, use only a single channel if job.single_channel: cropped_slice.channel(ChannelType.RedChannel) # Add the image to the cropped stack cropped_stack.append(cropped_slice) return cropped_stack
def resize_image(im, width=None, height=None, fixed=False, quality=86, image_type='image/jpeg', degrees=0): """ 返回的是blob类型的,取data """ w, h = get_im_size(im) #w, h 原始尺寸 # size means what u want if height is None and fixed: mode = 'fixed_width' times = w/float(width) size = [w/times, h/times] elif width is None and fixed: mode = 'fixed_height' times = h/float(height) size = [w/times, h/times] elif height is None and width is None: # 必须要指定 width or height raise Exception else: width = width or w height = height or h size = [width, height] if fixed: mode = 'fixed_both' else: mode = 'auto' if mode == 'fixed_both': # get the pre_thumbnail then cut! m = max(size[0]/float(w), size[1]/float(h)) #max_thumbnail_rate 不裁剪的缩放比 if m> 1: m=1 im.scale(list_to_size([w*m, h*m])) n_w, n_h = get_im_size(im) size= [min(size[0],n_w), min(size[1], n_h)] # # 最后的图片尺寸 in case, the image size is not big enough width, height = size left = int((n_w-width)/2.0) top = int((n_h-height)/2.0) box = Geometry(width, height, left, top) im.crop(box) else: size = [min(size[0], w), min(size[1], h)] im.scale(list_to_size(size)) if degrees and isinstance(degrees, (int, float)): # 旋转正向 im.rotate(int(degrees)) # quality im.profile("*", Blob()) # 清掉exif信息 im.quality(quality) f = Blob() if image_type in ['image/png', 'png']: image_type = 'png' elif image_type in ['webp', 'image/webp']: image_type = 'webp' else: image_type = 'jpg' if image_type in ['jpg', 'jpeg']: # 填充白色背景 base_im = Image(im.size(), '#ffffff') base_im.composite(im, 0, 0, co.OverCompositeOp) im = base_im im.write(f, image_type) return getattr(f, 'data')
from os import listdir, mkdir, path from pgmagick import Image, GravityType, CompositeOperator test_dir = path.join(path.curdir, "testdata") layer = Image(path.join(test_dir, "New_256x256.png")) output_dir = path.join(test_dir, input("Bitte den Speicherort angeben (Ordner reicht): ")) if not path.isdir(output_dir): mkdir(output_dir) for file in listdir(test_dir): if file.endswith(".jpg"): img = Image(path.join(test_dir, file)) img.composite(layer, GravityType.NorthEastGravity, CompositeOperator.OverCompositeOp) img.write(output_dir + "\\" + file)
line_inputs = list(filter(None, panel.split('\n'))) for line_input in line_inputs: split_line_input = line_input.split(':') actor = split_line_input[0] line = split_line_input[1] if "," in actor: split_actor = actor.split(",") actor = split_actor[0] attitude = split_actor[1] else: attitude = "neutral" lines.append({ "actor": actor.strip(), "attitude": attitude.strip(), "line": line.strip() }) panels.append(lines) num = 0 for panel in panels: bg = Image('backgrounds/{}.png'.format(background)) line_num = 1 for line in panel: actor = Image('sprites/{}/{}.png'.format(line['actor'], line['attitude'])) draw_line = DrawableText(20 * line_num, 95, line['line']) bg.composite(actor, 20 * line_num, 100, co.OverCompositeOp) bg.draw(draw_line) line_num = line_num + 4 bg.write('output{}.png'.format(num)) num = num + 1
def extract_substack_no_rotation( job ): """ Extracts a sub-stack as specified in the passed job without respecting rotation requests. A list of pgmagick images is returned -- one for each slice, starting on top. """ # The actual bounding boxes used for creating the images of each stack # depend not only on the request, but also on the translation of the stack # wrt. the project. Therefore, a dictionary with bounding box information for # each stack is created. s_to_bb = {} for stack in job.stacks: # Retrieve translation relative to current project translation = ProjectStack.objects.get( project_id=job.project_id, stack_id=stack.id).translation x_min_t = job.x_min - translation.x x_max_t = job.x_max - translation.x y_min_t = job.y_min - translation.y y_max_t = job.y_max - translation.y z_min_t = job.z_min - translation.z z_max_t = job.z_max - translation.z # Calculate the slice numbers and pixel positions # bound to the stack data. px_x_min = to_x_index(x_min_t, job) px_x_max = to_x_index(x_max_t, job) px_y_min = to_y_index(y_min_t, job) px_y_max = to_y_index(y_max_t, job) px_z_min = to_z_index(z_min_t, job) px_z_max = to_z_index(z_max_t, job) # Because it might be that the cropping goes over the # stack bounds, we need to calculate the unbounded height, # with and an offset. px_x_min_nobound = to_x_index(x_min_t, job, False) px_x_max_nobound = to_x_index(x_max_t, job, False) px_y_min_nobound = to_y_index(y_min_t, job, False) px_y_max_nobound = to_y_index(y_max_t, job, False) width = px_x_max_nobound - px_x_min_nobound height = px_y_max_nobound - px_y_min_nobound px_x_offset = abs(px_x_min_nobound) if px_x_min_nobound < 0 else 0 px_y_offset = abs(px_y_min_nobound) if px_y_min_nobound < 0 else 0 # Create a dictionary entry with a simple object class BB: pass bb = BB() bb.px_x_min = px_x_min bb.px_x_max = px_x_max bb.px_y_min = px_y_min bb.px_y_max = px_y_max bb.px_z_min = px_z_min bb.px_z_max = px_z_max bb.px_x_offset = px_x_offset bb.px_y_offset = px_y_offset bb.width = width bb.height = height s_to_bb[stack.id] = bb # Get number of wanted slices px_z_min = to_z_index(job.z_min, job) px_z_max = to_z_index(job.z_max, job) n_slices = px_z_max + 1 - px_z_min # The images are generated per slice, so most of the following # calculations refer to 2d images. # Each stack to export is treated as a separate channel. The order # of the exported dimensions is XYCZ. This means all the channels of # one slice are exported, then the next slice follows, etc. cropped_stack = [] # Accumulator for estimated result size estimated_total_size = 0 # Iterate over all slices for nz in range(n_slices): for stack in job.stacks: bb = s_to_bb[stack.id] # Shortcut for tile width and height tile_width = stack.tile_width tile_height = stack.tile_height # Get indices for bounding tiles (0 indexed) tile_x_min = int(bb.px_x_min / tile_width) tile_x_max = int(bb.px_x_max / tile_width) tile_y_min = int(bb.px_y_min / tile_height) tile_y_max = int(bb.px_y_max / tile_height) # Get the number of needed tiles for each direction num_x_tiles = tile_x_max - tile_x_min + 1 num_y_tiles = tile_y_max - tile_y_min + 1 # Associate image parts with all tiles image_parts = [] x_dst = bb.px_x_offset for nx, x in enumerate( range(tile_x_min, tile_x_max + 1) ): # The min x,y for the image part in the current tile are 0 # for all tiles except the first one. cur_px_x_min = 0 if nx > 0 else bb.px_x_min - x * tile_width # The max x,y for the image part of current tile are the tile # size minus one except for the last one. if nx < (num_x_tiles - 1): cur_px_x_max = tile_width - 1 else: cur_px_x_max = bb.px_x_max - x * tile_width # Reset y destination component y_dst = bb.px_y_offset for ny, y in enumerate( range(tile_y_min, tile_y_max + 1) ): cur_px_y_min = 0 if ny > 0 else bb.px_y_min - y * tile_height if ny < (num_y_tiles - 1): cur_px_y_max = tile_height - 1 else: cur_px_y_max = bb.px_y_max - y * tile_height # Create an image part definition z = bb.px_z_min + nz path = job.get_tile_path(stack, (x, y, z)) try: part = ImagePart(path, cur_px_x_min, cur_px_x_max, cur_px_y_min, cur_px_y_max, x_dst, y_dst) image_parts.append( part ) except: # ignore failed slices pass # Update y component of destination position y_dst += cur_px_y_max - cur_px_y_min # Update x component of destination position x_dst += cur_px_x_max - cur_px_x_min # Write out the image parts and make sure the maximum allowed file # size isn't exceeded. cropped_slice = None for ip in image_parts: # Get (correctly cropped) image image = ip.get_image() # Estimate total file size and abort if this exceeds the # maximum allowed file size. estimated_total_size = estimated_total_size + ip.estimated_size if estimated_total_size > settings.GENERATED_FILES_MAXIMUM_SIZE: raise ValueError("The estimated size of the requested image " "region is larger than the maximum allowed " "file size: %0.2f > %s Bytes" % \ (estimated_total_size, settings.GENERATED_FILES_MAXIMUM_SIZE)) # It is unfortunately not possible to create proper composite # images based on a canvas image newly created like this: # cropped_slice = Image( Geometry(bb.width, bb.height), Color("black")) # Therefore, this workaround is used. if not cropped_slice: cropped_slice = Image(image) cropped_slice.backgroundColor("black") cropped_slice.erase() # The '!' makes sure the aspect ration is ignored cropped_slice.scale('%sx%s!' % (bb.width, bb.height)) # Draw the image onto result image cropped_slice.composite( image, ip.x_dst, ip.y_dst, co.OverCompositeOp ) # Delete tile image - it's not needed anymore del image if cropped_slice: # Optionally, use only a single channel if job.single_channel: cropped_slice.channel( ChannelType.RedChannel ) # Add the image to the cropped stack cropped_stack.append( cropped_slice ) return cropped_stack
image_path = sys.argv[1] tile_size = int(sys.argv[2]) # Make sure the file actually exists if not os.path.exists(image_path): print >> sys.stderr, "Could not find file!" sys.exit(1) # Get properties of image image = Image(image_path) image_width = image.size().width() image_height = image.size().height() image_name = image.fileName() # If the image has the correct size, just exit if image_width == tile_size and image_height == tile_size: sys.exit(0) # A new image with the correct size is needed, create it geometry = Geometry(tile_size, tile_size) color = Color("black") new_image = Image(geometry, color) # Copy original image to position 0,0 of new image new_image.composite(image, 0, 0, co.OverCompositeOp) # Override original image new_image.write(image_name) print >> sys.stdout, "Corrected " + image_name + " from " + str(image_width) + "x" + str(image_height) + " to " + str(tile_size) + "x" + str(tile_size)