pool->getImage()); $image_x = $image_to_superpose->getImageWidth(); $image_y = $image_to_superpose->getImageHeight(); if ($image_x < 32 || $image_y < 32) { throw new \Exception('Image too small.'); } $this->current_image = $image_to_superpose; $nb_images = $this->config->get('assembler.superpose.min_num_images', 5); for ($i = 0; $i < $nb_images; $i++) { $this->current_image = $this->superpose(); } $this->current_image->writeImage($file); } public function superpose() { return $this->superposeOneImage($this->current_image, new \Imagick($this->pool->getImage())); } /** * Superposes one image in the current image. * This method must only be called by the assembler_superpose thread ! * * @param \Imagick $current_image * @param \Imagick $image_to_superpose * * @return \Imagick * @throws \Exception */ private function superposeOneImage($current_image, $image_to_superpose) { if ($this->config->get('assembler.superpose.variante', 0) === 1) { $current_image->brightnessContrastImage(0.99, 1); } if ($image_to_superpose->getColorspace() !== \Imagick::COLORSPACE_RGB) { $image_to_superpose->setColorspace(\Imagick::COLORSPACE_RGB); } # If the image is bigger than current image, scale it down to 1/2 of final picture dimensions # (while keeping its ratio) $image_x = $image_to_superpose->getImageWidth(); $image_y = $image_to_superpose->getImageHeight(); if ($image_x > $this->config->get('assembler.sizex') || $image_y > $this->config->get('assembler.sizey')) { try { $image_to_superpose->scaleImage($this->config->get('assembler.sizex') / 2, $this->config->get('assembler.sizey') / 2, true); } catch (\ImagickException $e) { } } # Scale down/up image if required. /*scaleValue = self.CONFIG["assembler.superpose.scale"] if str(scaleValue) != "1.0": try: imageToSuperpose.thumbnail((int(float(imagex)*scaleValue),int(float(imagey)*scaleValue)),Image.ANTIALIAS) except TypeError: #TypeError: unsubscriptable object ; Spurious exception in PIL. :-( raise BadImage (imagex,imagey) = imageToSuperpose.size*/ # Compensate for poorly-contrasted images on the web /*try: imageToSuperpose = ImageOps.autocontrast(imageToSuperpose) except TypeError: # Aaron tells me that this exception occurs with PNG images. raise BadImage*/ # Some image are too white. # For example, the photo of a coin on a white background. # These picture degrad the quality of the final image. # We try to dectect them by summing the value of the pixels # on the borders. # If the image is considered "white", we invert it. /*pixelcount = 1 # 1 to prevent divide by zero error. valuecount = 0 try: for x in range(0,imagex,20): (r,g,b) = imageToSuperpose.getpixel((x,5)) valuecount += r+g+b (r,g,b) = imageToSuperpose.getpixel((x,imagey-5)) valuecount += r+g+b pixelcount += 2 for y in range(0,imagey,20): (r,g,b) = imageToSuperpose.getpixel((5,y)) valuecount += r+g+b (r,g,b) = imageToSuperpose.getpixel((imagex-5,y)) valuecount += r+g+b pixelcount += 2 except TypeError: #unsubscriptable object Arrggghh... not again ! raise BadImage # Aggrrreeeuuuu... # If the average r+g+b of the border pixels exceed this value, # we consider the image is too white, and we invert it. if (100*(valuecount/(255*3))/pixelcount)>60: # Cut at 60%. (100% is RGB=(255,255,255)) imageToSuperpose = ImageOps.invert(imageToSuperpose)*/ $paste_coords_x = random_int(-$image_x, $this->config->get('assembler.sizex')); $paste_coords_y = random_int(-$image_y, $this->config->get('assembler.sizey')); # Darken image borders $image_to_superpose = $this->darkenImageBorder($image_to_superpose, 30); if ($this->config->get('assembler.superpose.randomrotation', false)) { $image_to_superpose->rotateImage('none', random_int(0, 359)); $image_to_superpose = $this->darkenImageBorder($image_to_superpose, 30); } // mask_image = ImageOps.autocontrast(imageToSuperpose.convert('L')) // if (self.CONFIG["assembler.superpose.variante"]==1) and (random.randint(0,100)<5): # Invert the transparency of 5% of the images (Except if we are in variante 1 mode) // mask_image = ImageOps.invert(mask_image) $current_image->compositeImage($image_to_superpose, \Imagick::COMPOSITE_DEFAULT, $paste_coords_x, $paste_coords_y); if ($this->config->get('assembler.superpose.variante') === 0) { $current_image->equalizeImage(); } else { $current_image->autoLevelImage(); } return $current_image; } /** * @param \Imagick $image * @param int|null $border_size * * @return \Imagick */ private function darkenImageBorder(Imagick $image, $border_size = null) { if (null === $border_size) { $border_size = $this->config->get('assembler.superpose.bordersmooth'); } $image_x = $image->getImageWidth(); $image_y = $image->getImageHeight(); for ($i = 0; $i < $border_size; $i++) { $draw = new \ImagickDraw(); $draw->setStrokeOpacity(($border_size-$i)/$border_size); $draw->setStrokeWidth(1); $draw->setStrokeColor('black'); $draw->setFillColor('none'); $draw->rectangle($i, $i, $image_x - $i, $image_y - $i); $image->drawImage($draw); } return $image; } public function display() { // TODO: Implement display() method. } }