示例#1
0
 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
示例#3
0
    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)
示例#4
0
    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
示例#6
0
    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')
示例#8
0
    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"
示例#9
0
    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)
示例#10
0
    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
示例#11
0
	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
示例#12
0
    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
示例#13
0
	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
示例#14
0
 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)
示例#15
0
    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
示例#16
0
    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)
示例#17
0
    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"
示例#18
0
    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
示例#19
0
	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
示例#20
0
    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"
示例#21
0
    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"
示例#22
0
    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"
示例#23
0
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
示例#24
0
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))
示例#25
0
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
示例#26
0
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
示例#27
0
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')
示例#28
0
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)
示例#29
0
    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
示例#30
0
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
示例#31
0
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)