diff --git a/src/Assembler/Superpose.php b/src/Assembler/Superpose.php index 3d812db..924f047 100644 --- a/src/Assembler/Superpose.php +++ b/src/Assembler/Superpose.php @@ -21,14 +21,9 @@ class Superpose extends Assembler */ public function saveTo($file) { - $image_to_superpose = new \Imagick($this->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; + $this->current_image = new \Imagick(); + $this->current_image->setSize($this->config->get('assembler.sizex'), $this->config->get('assembler.sizey')); + $this->current_image->newImage($this->config->get('assembler.sizex'), $this->config->get('assembler.sizey'), 'none'); $nb_images = $this->config->get('assembler.superpose.min_num_images', 5); for ($i = 0; $i < $nb_images; $i++) { @@ -65,6 +60,10 @@ class Superpose extends Assembler # (while keeping its ratio) $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.'); + } + 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); @@ -73,13 +72,12 @@ class Superpose extends Assembler } # 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*/ + $scale_value = $this->config->get('assembler.superpose.scale', 1); + if ($scale_value !== 1) { + $image_to_superpose->thumbnailImage($image_x * $scale_value, $image_y * $scale_value); + } + $image_x = $image_to_superpose->getImageWidth(); + $image_y = $image_to_superpose->getImageHeight(); # Compensate for poorly-contrasted images on the web /*try: @@ -93,44 +91,51 @@ class Superpose extends Assembler # 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... - + $pixel_count = 1; // to prevent divide by zero error. + $value_count = 0; + for ($x = 0; $x < $image_x; $x += 20) { + $pixel = $image_to_superpose->getImagePixelColor($x, 5); + $value_count += array_sum($pixel->getColor()); + $pixel = $image_to_superpose->getImagePixelColor($x, $image_y - 5); + $value_count += array_sum($pixel->getColor()); + $pixel_count += 2; + } + for ($y = 0; $y < $image_y; $y += 20) { + $pixel = $image_to_superpose->getImagePixelColor(5, $y); + $value_count += array_sum($pixel->getColor()); + $pixel = $image_to_superpose->getImagePixelColor($image_x - 5, $y); + $value_count += array_sum($pixel->getColor()); + $pixel_count += 2; + } # 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)*/ + if (100 * $value_count / (255 * 3) / $pixel_count > 60) { + $image_to_superpose->negateImage(false); + } - $paste_coords_x = random_int(-$image_x, $this->config->get('assembler.sizex')); - $paste_coords_y = random_int(-$image_y, $this->config->get('assembler.sizey')); + $paste_coords_x = random_int(-($image_x/2), $this->config->get('assembler.sizex')-$image_x); + $paste_coords_y = random_int(-($image_y/2), $this->config->get('assembler.sizey')-$image_y); # Darken image borders - $image_to_superpose = $this->darkenImageBorder($image_to_superpose, 30); + $image_to_superpose = $this->darkenImageBorder($image_to_superpose); 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); + $image_to_superpose = $this->darkenImageBorder($image_to_superpose); } -// mask_image = ImageOps.autocontrast(imageToSuperpose.convert('L')) + // help for mask : https://phpimagick.com/Tutorial/backgroundMasking + $image_to_superpose->setImageMatte(true); + $mask_image = clone $image_to_superpose; + $mask_image->setImageType(Imagick::IMGTYPE_GRAYSCALE); + $mask_image->transformImageColorSpace(Imagick::COLORSPACE_GRAY); -// 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) + # Invert the transparency of 5% of the images (Except if we are in variante 1 mode) + if ($this->config->get('assembler.superpose.variante') === 1 && random_int(0, 100) < 5) { + $mask_image->negateImage(true); + } + + $image_to_superpose->compositeImage($mask_image, \Imagick::COMPOSITE_COPYOPACITY, 0, 0); $current_image->compositeImage($image_to_superpose, \Imagick::COMPOSITE_DEFAULT, $paste_coords_x, $paste_coords_y); if ($this->config->get('assembler.superpose.variante') === 0) {