2013-05-06 38 views
10

Làm thế nào người ta có thể chỉ định một hình ảnh và áp dụng một gradient trong suốt xuyên tâm nơi nó mất dần radially. Tôi chưa cài đặt Imagemagick.Làm thế nào tôi có thể có một gradient trong suốt đẹp xuyên suốt được áp dụng cho một hình ảnh với PHP?

dụ Marginal:

Gradient Transparent image fade PHP

+0

http://stackoverflow.com/questions/6615602/radial-gradients-with-opacity-in-php?rq=1 # answer-6615727 –

+0

Sử dụng CSS: http://stackoverflow.com/a/4527735/738201 – Chad

+0

Kịch bản trường hợp tồi tệ hơn, bạn có thể vẽ đường viền vòng tròn PNG bằng GD nguyên thủy, nhưng thay vì áp dụng thay đổi màu, hãy áp dụng thay đổi độ mờ. Sau đó, phủ lớp PNG ở phía trên hình ảnh hiện tại của bạn. Tôi không có bất kỳ mã nào cho điều đó, nhưng nó có thể cung cấp cho bạn một số ý tưởng mới về cụm từ tìm kiếm. – halfer

Trả lời

3

Nhờ chức năng được liên kết bởi @Baba tôi đã có thể thay đổi tập lệnh để cho phép hiệu ứng họa tiết bán trong suốt.

<?php 
class PhotoEffect 
{ 
    private $_photoLocation; 
    private $_width; 
    private $_height; 
    private $_type; 

    private $_originalImage; 
    private $_afterImage; 

    /** 
    * Load image URL in constructor 
    */ 
    final public function __construct($photoLocation) 
    { 
    $this->_photoLocation = $photoLocation; 
    if (!$size = @getimagesize($this->_photoLocation)){ 
     throw new Exception('Image cannot be handled'); 
    } 
    $this->_width = $size[0]; 
    $this->_height = $size[1]; 
    $this->_type = $size[2]; 


    switch ($this->_type) { 
     case IMAGETYPE_GIF: 
     $this->_originalImage = imagecreatefromgif($this->_photoLocation); 
     break; 
     case IMAGETYPE_JPEG: 
     $this->_originalImage = imagecreatefromjpeg($this->_photoLocation); 
     break; 
     case IMAGETYPE_PNG: 
     $this->_originalImage = imagecreatefrompng($this->_photoLocation); 
     break; 
     default: 
     throw new Exception('Unknown image type'); 
    } 
    } 

    /** 
    * Destroy created images 
    */ 
    final private function __destruct() { 
    if (!empty($this->_originalImage)) 
    { 
     imagedestroy($this->_originalImage); 
    } 

    if (!empty($this->_afterImage)) 
    { 
     imagedestroy($this->_afterImage); 
    } 
    } 

    /** 
    * Apply vignette effect 
    */ 
    final public function Vignette($sharp=0.4, $level=1, $alpha=1) 
    { 
    if (empty($this->_originalImage)) 
    { 
     throw new Exception('No image'); 
    } 

    if (!is_numeric($sharp) || !($sharp>=0 && $sharp<=10)) 
    { 
     throw new Exception('sharp must be between 0 and 10');    
    } 

    if (!is_numeric($level) || !($level>=0 && $level<=1)) 
    { 
     throw new Exception('level must be between 0 and 10');    
    } 

    if (!is_numeric($alpha) || !($alpha>=0 && $alpha<=10)) 
    { 
     throw new Exception('alpha must be between 0 and 1');   
    } 

    $this->_afterImage = imagecreatetruecolor($this->_width, $this->_height); 
    imagesavealpha($this->_afterImage, true); 
    $trans_colour = imagecolorallocatealpha($this->_afterImage, 0, 0, 0, 127); 
    imagefill($this->_afterImage, 0, 0, $trans_colour); 


    for($x = 0; $x < $this->_width; ++$x){ 
     for($y = 0; $y < $this->_height; ++$y){ 
     $index = imagecolorat($this->_originalImage, $x, $y); 
     $rgb = imagecolorsforindex($this->_originalImage, $index); 

     $l = sin(M_PI/$this->_width * $x) * sin(M_PI/$this->_height * $y); 
     $l = pow($l, $sharp); 

     $l = 1 - $level * (1 - $l); 

     $rgb['red'] *= $l; 
     $rgb['green'] *= $l; 
     $rgb['blue'] *= $l; 
     $rgb['alpha'] = 127 - (127 * ($l*$alpha)); 


     $color = imagecolorallocatealpha($this->_afterImage, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']); 

     imagesetpixel($this->_afterImage, $x, $y, $color); 
     } 
    } 

    } 


    /** 
    * Ouput PNG with correct header 
    */ 
    final public function OutputPng() 
    { 
    if (empty($this->_afterImage)) 
    { 
     if (empty($this->_originalImage)) 
     { 
     throw new Exception('No image'); 
     } 
     $this->_afterImage = $this->_originalImage; 
    } 

    header('Content-type: image/png'); 
    imagepng($this->_afterImage); 
    } 

    /** 
    * Save PNG 
    */ 
    final public function SavePng($filename) 
    { 
    if (empty($filename)) { 
     throw new Exception('Filename is required'); 
    } 

    if (empty($this->_afterImage)) 
    { 
     if (empty($this->_originalImage)) 
     { 
     throw new Exception('No image'); 
     } 
     $this->_afterImage = $this->_originalImage; 
    } 

    imagepng($this->_afterImage, $filename); 
    } 

} 


/** 
* How to use 
*/ 
$effect = new PhotoEffect('test.jpg'); 
$effect->Vignette(); 
$effect->OutputPng(); 
?> 

Working phpfiddle bằng hình ảnh duy nhất tôi có thể tìm thấy trên máy chủ của họ, vì vậy không lớn lắm.

+0

Hey Hugo mã này dường như không hoạt động đối với tôi. Không chắc chắn về việc bỏ phiếu xuống. –

+0

Tôi đã cập nhật toàn bộ mã cho một lớp học. Tôi đã làm cho nó như thế này để có thể thêm các hiệu ứng khác như là –

+0

Đã thử một tệp PNG thông thường và nhận được điều này: 'PHP Fatal error: Uncaught exception 'Exception' với thông điệp 'Image cannot be handle'' –

17

Giới thiệu

Tôi nghĩ rằng bạn sẽ nhận được ImageMagick cài đặt bởi vì những gì bạn muốn là một vignette tác đơn giản, bạn có thể dễ dàng để có ImageMagic (convert input.jpg -background black -vignette 70x80 output.png) mà không phải lặp lại từng pixel có thể rất chậm khi xử lý hình ảnh lớn

gốc Hình ảnh

$file = __DIR__ . "/golf.jpg"; 

enter image description here

Hiệu lực thi hành 1

$image = new imagick($file); 
$image->vignetteImage(20, 20, 40, - 20); 
header("Content-Type: image/png"); 
echo $image; 

enter image description here

Effect 2

$image = new imagick($file); 
$image->vignetteImage(100, 100, 200, 200); 
header("Content-Type: image/png"); 
echo $image; 

enter image description here

mờ nét ảnh với GD

Vâng, nếu bạn buộc phải sử dụng GB ... Sử dụng có thể sử dụng cool vignette script

function vignette($im) { 
    $width = imagesx($im); 
    $height = imagesy($im); 

    $effect = function ($x, $y, &$rgb) use($width, $height) { 
     $sharp = 0.4; // 0 - 10 small is sharpnes, 
     $level = 0.7; // 0 - 1 small is brighter 
     $l = sin(M_PI/$width * $x) * sin(M_PI/$height * $y); 
     $l = pow($l, $sharp); 
     $l = 1 - $level * (1 - $l); 
     $rgb['red'] *= $l; 
     $rgb['green'] *= $l; 
     $rgb['blue'] *= $l; 
    }; 

    for($x = 0; $x < imagesx($im); ++ $x) { 
     for($y = 0; $y < imagesy($im); ++ $y) { 
      $index = imagecolorat($im, $x, $y); 
      $rgb = imagecolorsforindex($im, $index); 
      $effect($x, $y, $rgb); 
      $color = imagecolorallocate($im, $rgb['red'], $rgb['green'], $rgb['blue']); 

      imagesetpixel($im, $x, $y, $color); 
     } 
    } 
    return (true); 
} 

nhanh hơn GD tiếp cận họa tiết này

Một tốt hơn tiếp cận được sử dụng trong GD Filter testing sẽ ... để tạo ra một mặt nạ và hơn nằm

$overlay = 'vignette_white.png'; 
    $png = imagecreatefrompng($overlay); 
    imagecopyresampled($filter, $png, 0, 0, 0, 0, $width, $height, $width, $height); 

Những bất lợi duy nhất là hình ảnh phải có cùng kích thước với mặt nạ để hiệu ứng trông đẹp hơn

Kết luận

Nếu đây là những gì bạn có nghĩa là bởi radial transparent gradient sau đó tôi khuyên bạn để có được ImageMagic nếu không ít nhất là người phụ nữ hình ảnh dễ thương.

+0

haha ​​đúng và cảm ơn bạn đã trả lời nhưng gradient hình ảnh mờ dần thành màu trắng không trong suốt. Đơn giản là không thể? Nếu bạn nhận thấy hình ảnh cận biên trong bài đăng có thể mờ dần ra bất kỳ nền nào. –

+0

Bạn có thể dễ dàng thay đổi nền trong phiên bản GB .... Bạn có thể sử dụng Imagemagic không? – Baba

0

Tôi biết rằng đây là một câu hỏi liên quan đến PHP, nhưng bạn có thể đạt được các gradient trong suốt đẹp với việc sử dụng phần tử canvas javascript và html5.

Vì vậy, tôi đã viết kịch bản nhỏ này rằng:

  • phát hiện trình duyệt hỗ trợ yếu tố canvas, nếu trình duyệt không hỗ trợ canvas (may mắn chỉ có một vài phần trăm của người sử dụng là trái) sau đó hình ảnh đầy đủ sẽ được hiển thị.
  • tạo vải và gắn thêm yếu tố sau ảnh
  • luận trong create_gradient() chức năng có thể được thay đổi cho tùy chỉnh hình dạng
  • nó hoạt động với tất cả các định dạng ảnh phổ biến (thử nghiệm với .jpg, .bmp, .gif, .png)
  • bạn có thể thêm 'colorstops' (grd.addColorStop()) để thay đổi dòng chảy của gradient

kịch bản

window.onload = function() { 
    if (typeof CanvasRenderingContext2D !== 'function') { 
     document.getElementById('gradient-image').style.visibility = "visible"; 
     return; 
    } 

    var image = document.getElementById('gradient-image'); 

    // these are the default values, change them for custom shapes 
    create_gradient(image, image.width/2, image.height/2, image.height/4, image.width/2, image.height/2, image.height/2); 
} 

function create_gradient(image, start_x, start_y, start_r, end_x, end_y, end_r){ 

    var canvas = document.createElement('canvas'); 

    var parent = image.parentNode; 
    if (parent.lastchild == image) parent.appendChild(canvas); 
    else parent.insertBefore(canvas, image.nextSibling); 

    canvas.width = image.width; 
    canvas.height = image.height; 

    var context = canvas.getContext('2d'); 

    var grd = context.createRadialGradient(start_x, start_y, start_r, end_x, end_y, end_r); 
    grd.addColorStop(0, 'rgba(0,0,0,1)'); 
    // grd.addColorStop(0.2, 'rgba(0,0,0,0.8)'); 
    grd.addColorStop(1, 'rgba(0,0,0,0)'); 

    context.fillStyle = grd; 
    context.fillRect(0, 0, image.width, image.height); 

    var grd_data = context.getImageData(0, 0, image.width, image.height); 

    context.drawImage(image, 0, 0); 
    var img_data = context.getImageData(0, 0, image.width, image.height); 

    var grd_pixel = grd_data.data; 
    var img_pixel = img_data.data; 
    var length = img_data.data.length 

    for (i = 3; i < length; i += 4) { 
     img_pixel[i] = grd_pixel[i]; 
    } 
    context.putImageData(img_data, 0, 0); 
} 

html

<img id="gradient-image"src=""> 

css

#gradient-image { 
    position: absolute; 
    visibility: hidden; 
} 
+0

Xem xét bài viết này (vài tháng tuổi, nhưng vẫn còn) http://thenextweb.com/apps/2012/10/01/internet-explorer-8-falls-25-market-share-firefox-15-passes-10- mark-chrome-loses-users/có hơn 25% vẫn còn trên IE8 hoặc thấp hơn. Vì vậy, ngay cả với một giảm lớn đến 15% mà tôi nghi ngờ đã happend, bạn đang nói với rất nhiều người rằng họ không đủ tốt cho trang web của bạn. Và xem xét canvas/javascript là khủng khiếp chậm trên các thiết bị Android và các thiết bị iOS cũ hơn, tôi chắc chắn sẽ không sử dụng javascript cho những thứ như thế này. –

Các vấn đề liên quan