2014-10-10 3 views
0

У меня есть функция, которая изменяет размер изображений. Он работает хорошо в большинстве случаев, но по некоторым причинам, в некоторых случаях результат изменения размера изображения полностью отличается от изображения, изначально содержащегося. Функция выглядит следующим образом:Ошибка изменения размера

function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) { 


    $defaults = array(
     'output' => 'file', 
     'isFile' => true, 
     'quality' => '100', 
     'preserveAnimation' => false, 
     'offsetTop' => 0, 
     'offsetLeft' => 0, 
     'offsetType' => 'percent' 
    ); 

    foreach ($defaults as $k => $v) { 
     if (!isset($options[$k])) { 
      $options[$k] = $v; 
     } 
    } 

    if ($options['isFile']) { 
     $image_info = getimagesize($source); 
     $image = null; 
     switch ($image_info[2]) { 
      case IMAGETYPE_JPEG: 
       $image = imagecreatefromjpeg($source); 
       break; 
      case IMAGETYPE_PNG: 
       $image = imagecreatefrompng($source); 
       break; 
      case IMAGETYPE_GIF: 
       $image = imagecreatefromgif($source); 
       break; 
      case IMAGETYPE_BMP: 
       $image = imagecreatefromwbmp($source); 
       break; 
      default : 
       return false; 
     } 
    } else { 
     $image = imagecreatefromstring($source); 
    } 

    //we have an image resource 
    $iwidth = imagesx($image); 
    $iheight = imagesy($image); 

    //We need $width and $height for this call 
    if (QM::isAcceptableProfilePhotoSize($width, $height) == false) 
    { 
     throw new Exception("Size of ".$width."x".$height." is not supported"); 
    } 

    //determine ratios 
    $wratio = $width/$iwidth; 
    $hratio = $height/$iheight; 
    $mratio = min(array($wratio, $hratio)); 

    $rimage = null; 

    switch ($resizeMode) { 
     case 'fit': 
      $rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio); 
      $image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight); 
      break; 
     case 'crop': 
      $rratio = $width/$height; 


      if ($rratio < 1) { 
       $nwidth = $iwidth; 
       $nheight = $iwidth * 1/$rratio; 
       if ($nheight>$iheight) { 
        $nwidth = $nwidth*$iheight/$nheight; 
        $nheight = $iheight; 
       } 
      } else { 
       $nwidth = $iheight*$rratio; 
       $nheight = $iheight; 
       if ($nwidth>$iwidth) { 
        $nheight = $nheight*$iwidth/$nwidth; 
        $nwidth = $iwidth; 
       } 
      } 
      switch ($options['offsetType']) { 
       case 'percent': 
        $sx = ($iwidth-$nwidth)*$options['offsetLeft']/100; 
        $sy = ($iheight-$nheight)*$options['offsetTop']/100; 
        break; 
       default : 
        return false; 
      } 

      $rimage = imagecreatetruecolor($width, $height); 
      $image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight); 
      break; 
     default : 
      return false; 
      break; 
    } 

    if (!is_writeable(dirname($destination))) { 
     throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable"); 
    } 

    switch ($options['output']) { 
     case 'file': 
      switch ($image_info[2]) { 
       case IMAGETYPE_JPEG: 
        return imagejpeg($rimage, $destination, $options['quality']); 
       case IMAGETYPE_PNG: 
        return imagepng($rimage, $destination, 0); 
       case IMAGETYPE_GIF: 
        return imagegif($rimage, $destination); 
       case IMAGETYPE_BMP: 
        return imagejpeg($rimage, $destination, $options['quality']); 
       default : 
        return false; 
        break; 
      } 
      return true; 
      break; 
     default : 
      return false; 
      break; 
    } 
} 

Пример изображения вызывает проблему: enter image description here

Этот образ успешно загружен, но когда я пытаюсь изменить его, в результате изображение:

enter image description here

Я вызываю функцию следующим образом:

image_resize($ofile, $cfile, $width, $height, 'crop', 'jpeg'); 

Где $ofile находится исходный файл, $cfile является планируемым местом назначения, $width является требуемой шириной (90 в этом случае), $height является искомой высотой (90 в этом случае), 'crop' это выбранная стратегия и 'jpeg' определенные $type Значение, которое не используется в функции (как я уже упоминал, я унаследовал код). Кроме того, единственным примером, где может быть воспроизведена проблема, является прикрепленное изображение, которое является png, другие png-файлы загружаются правильно, поэтому я не понимаю причину проблемы и не знаю, как ее решить. Может ли кто-нибудь описать причину проблемы? Я долго искал и экспериментировал, не добившись успеха.

+0

http://stackoverflow.com/questions/24430176/trouble-cropping-and-resizing-image/24431514#24431514 – TBI

+0

Возможно, связанные с прозрачностью http://stackoverflow.com/questions/279236/how- do-i-resize-pngs-with-transparent-in-php? – Danack

ответ

1

я попробовал вашу функцию «image_resize» с птицей картины, и она отлично работает на моем компьютере, установлен ли я исходное изображение в формате JPG или PNG, он работает, как ожидалось:

resized bird

Однако почему бы не выбрать «вписаться» вместо «культуры», как так:

image_resize($ofile, $cfile, $width = 90, $height = 90, 'fit', 'jpeg'); 

Edit: на основе вопросов других людей о получении черного изображения после изменения размера PNG, это будет коррекция:

function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) { 

    $defaults = array(
     'output' => 'file', 
     'isFile' => true, 
     'quality' => '100', 
     'preserveAnimation' => false, 
     'offsetTop' => 0, 
     'offsetLeft' => 0, 
     'offsetType' => 'percent' 
    ); 

    foreach ($defaults as $k => $v) { 
     if (!isset($options[$k])) { 
      $options[$k] = $v; 
     } 
    } 

    if ($options['isFile']) { 
     $image_info = getimagesize($source); 
     $image = null; 
     switch ($image_info[2]) { 
      case IMAGETYPE_JPEG: 
       $image = imagecreatefromjpeg($source); 
       break; 
      case IMAGETYPE_PNG: 
       $image = imagecreatefrompng($source); 
       break; 
      case IMAGETYPE_GIF: 
       $image = imagecreatefromgif($source); 
       break; 
      case IMAGETYPE_BMP: 
       $image = imagecreatefromwbmp($source); 
       break; 
      default : 
       return false; 
     } 
    } else { 
     $image = imagecreatefromstring($source); 
    } 

    //we have an image resource 
    $iwidth = imagesx($image); 
    $iheight = imagesy($image); 

    //determine ratios 
    $wratio = $width/$iwidth; 
    $hratio = $height/$iheight; 
    $mratio = min(array($wratio, $hratio)); 

    $rimage = null; 

    switch ($resizeMode) { 
     case 'fit': 
      $rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio); 
      imagealphablending($rimage, false); 
      imagesavealpha($rimage, true); 
      $image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight); 
      break; 
     case 'crop': 
      $rratio = $width/$height; 


      if ($rratio < 1) { 
       $nwidth = $iwidth; 
       $nheight = $iwidth * 1/$rratio; 
       if ($nheight>$iheight) { 
        $nwidth = $nwidth*$iheight/$nheight; 
        $nheight = $iheight; 
       } 
      } else { 
       $nwidth = $iheight*$rratio; 
       $nheight = $iheight; 
       if ($nwidth>$iwidth) { 
        $nheight = $nheight*$iwidth/$nwidth; 
        $nwidth = $iwidth; 
       } 
      } 
      switch ($options['offsetType']) { 
       case 'percent': 
        $sx = ($iwidth-$nwidth)*$options['offsetLeft']/100; 
        $sy = ($iheight-$nheight)*$options['offsetTop']/100; 
        break; 
       default : 
        return false; 
      } 

      $rimage = imagecreatetruecolor($width, $height); 
      imagealphablending($rimage, false); 
      imagesavealpha($rimage, true); 
      $image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight); 
      break; 
     default : 
      return false; 
      break; 
    } 

    if (!is_writeable(dirname($destination))) { 
     throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable"); 
    } 

    switch ($options['output']) { 
     case 'file': 
      switch ($image_info[2]) { 
       case IMAGETYPE_JPEG: 
        return imagejpeg($rimage, $destination, $options['quality']); 
       case IMAGETYPE_PNG: 
        return imagepng($rimage, $destination, 0); 
       case IMAGETYPE_GIF: 
        return imagegif($rimage, $destination); 
       case IMAGETYPE_BMP: 
        return imagejpeg($rimage, $destination, $options['quality']); 
       default : 
        return false; 
        break; 
      } 
      return true; 
      break; 
     default : 
      return false; 
      break; 
    } 
} 
+0

«подгонка» деформирует изображение. «урожай» был выбран по какой-то причине. Вы успешно запускали его с помощью «урожая»? –

+0

Да, не было проблем с параметром «crop». (но он выращивает хвост птицы на правом краю, поэтому я предпочитаю «подгонку», и я не получаю деформированное изображение, image_resize автоматически вычисляет правильное соотношение ширины и высоты) – Yoric

+0

По деформации я имею в виду, что отношение ширины/высоты равно деформируется. Естественно, ширина этого изображения больше его высоты, поэтому, делая их равными, мы делаем их более тонкими по ширине, таким образом, мы деформируем картину. Кадрирование сохраняет правильную внешность изображения, но проблема состоит в том, чтобы вырезать детали. Я предпочитаю в своем случае режущую версию, чем деформирующую версию. Дело в том, что этот код с обрезкой на нескольких компьютерах генерирует черное изображение, и это проблема. Если вы не можете воспроизвести его, вы, вероятно, не сможете помочь. –

Смежные вопросы