2013-05-07 25 views
0

我有一個Perl腳本,它使用Image :: Magick perl模塊從Web窗體裁剪現有圖像(使用JCrop爲我提供寬度,高度,x,y)。由於裁剪後的圖像將用於響應式設計環境中,因此我將在網站的前端創建多種尺寸的圖像。尺寸以數組形式構建(如下面的代碼所示),並逐個處理以創建每個圖像大小。image :: Magick perl模塊 - 從一次讀取和一次寫入多次裁剪/調整大小的操作?

正如你將從下面的代碼中看到的,我最終必須打開圖像3次,並寫入3次......這似乎是相當過分的......所以我希望你們知道更好的方法來做這個。

我最初嘗試使用Image :: Magick來簡單地打開文件一次,運行「裁剪,調整大小,裁剪」的過程,然後寫一次圖像,但結果是可怕的。沒有一個座標可以正確翻譯,因此圖像甚至沒有接近用戶在網頁表單中所要求的大小......儘管數值完美無缺。

所以我向大家提出的問題是,是否有人能夠使用Image :: Magick執行單個「打開」(對已打開圖像進行多次操作),然後執行單個「寫入」 perl模塊?如果是這樣,你能否提供一個樣本,這將是我在下面發佈的代碼的一長串?我非常感謝可以給予的幫助。下面是我的代碼片段。很抱歉的過度評論,我想讓它儘可能容易用:)

#!/usr/bin/perl 

use Image::Magick; 
use CGI qw(:cgi-lib); 

&ReadParse(*input); 

############################## 
# Build array of sizes needed 
############################## 

my @sizes = ("1280","960","640","480","320","160"); 

foreach $size (@sizes) { 
    $resized = "/path/to/size/folders/$size\/$input{image_ID}\.png"; 

    $image = Image::Magick->new; 
    $x = $image->Read("/path/to/fullsize/image"); 

    ######################### 
    # Run the requested crop 
    ######################### 

    $x = $image->Crop(width=>$input{w},height=>$input{h},x=>$input{x},y=>$input{y}); 

    ######################## 
    # Write cropped version 
    ######################## 

    $x = $image->Write("$resized"); 

    ########################### 
    # Open the cropped version 
    ########################### 

    $image = Image::Magick->new; 
    $x = $image->Read("$resized"); 

    ############################################### 
    # Size the image down to +2 pixels all around 
    # to handle border opacity when pixel rounding 
    ############################################### 

    $temp_width = $size + 2; 
    $temp_height = ($temp_width * $input{h})/$input{w}; 

    ########################### 
    # Resize the cropped image 
    ########################### 

    $x = $image->Resize(width=>$temp_width, height=>$temp_height); 

    ################################ 
    # Write the newly resized image 
    ################################ 

    $x = $image->Write("$resized"); 

    ######################################## 
    # Calculate final dimensions and coords 
    ######################################## 

    $final_height = ($size * $temp_height)/$temp_width; 
    $final_x = 1; 
    $final_y = 1; 

    ############################### 
    # Open the newly resized image 
    ############################### 

    $image = Image::Magick->new; 
    $x = $image->Read("$resized"); 

    ####################################### 
    # Final crop the image for clean edges 
    ####################################### 

    $x = $image->Crop(width=>$size,height=>$final_height,x=>$final_x,y=>$final_y); 

    ######################################## 
    # Write the final cropped image for use 
    ######################################## 

    $x = $image->Write("$resized"); 
} 
+0

我不知道我理解正確,這一點,但你嘗試過複製對象閱讀一次之後,然後在每個對象上做翻譯。 – simbabque 2013-05-07 19:06:25

+0

我嘗試了nwellnhof發佈的以下內容,與您的建議類似。結果張貼在他的評論下方。 – 2013-05-08 15:56:14

回答

0

沿着沿您可以使用Clone方法來複制的圖像。另外,寫下圖像並在之後立即閱讀是多餘的。你可以試試下面的:

my @sizes = ("1280","960","640","480","320","160"); 

my $src_image = Image::Magick->new; 
$x = $src_image->Read("/path/to/fullsize/image"); 

######################### 
# Run the requested crop 
######################### 

$x = $src_image->Crop(width=>$input{w},height=>$input{h},x=>$input{x},y=>$input{y}); 

foreach $size (@sizes) { 
    my $image = $src_image->Clone; 

    $resized = "/path/to/size/folders/$size\/$input{image_ID}\.png"; 

    ############################################### 
    # Size the image down to +2 pixels all around 
    # to handle border opacity when pixel rounding 
    ############################################### 

    $temp_width = $size + 2; 
    $temp_height = ($temp_width * $input{h})/$input{w}; 

    ########################### 
    # Resize the cropped image 
    ########################### 

    $x = $image->Resize(width=>$temp_width, height=>$temp_height); 

    ######################################## 
    # Calculate final dimensions and coords 
    ######################################## 

    $final_height = ($size * $temp_height)/$temp_width; 
    $final_x = 1; 
    $final_y = 1; 

    ####################################### 
    # Final crop the image for clean edges 
    ####################################### 

    $x = $image->Crop(width=>$size,height=>$final_height,x=>$final_x,y=>$final_y); 

    ######################################## 
    # Write the final cropped image for use 
    ######################################## 

    $x = $image->Write("$resized"); 
} 
+0

我實現了你的建議,但由於某種原因,無論我操作什麼圖像,數組中的每個圖像大小都會導致白色背景上的1x1圖像。如果我註釋掉最後一個作物,它會起作用(每個圖像周圍都有+2像素)...所以它似乎不想處理「調整大小」命令,然後最終的「裁切」命令而不轉動圖像由於某種原因轉換爲1x1圖像。我有他們應該被寫入日誌文件的大小,他們都顯示正確。還有什麼想法?我非常感謝你的幫助。 – 2013-05-08 15:55:08

+2

使用'$ image-> Set(page =>'0x0 + 0 + 0');'裁剪後,您可能必須「修剪」圖像。 – nwellnhof 2013-05-08 18:14:32

0

很晚了這一點,但是這個工作對我來說,如果它可以幫助別人:

my $imageName = 'picture'; 
my $file = "tmp/original.jpg"; 

# Create the image object 
my $imageFile = Image::Resize->new($file); 

# Resize and save one... 
my $image = $imageFile->resize(800, 450); 
open(FH, ">$siteroot/user_pics/$imageName\_800x450.jpg"); 
print FH $image->jpeg(); 
close(FH); 

# Resize and save another... 
my $thumb = $imageFile->resize(224, 126); 
open(FH, ">$siteroot/user_pics/$imageName\_224x126.jpg"); 
print FH $thumb->jpeg(); 
close(FH); 

# etc... 

unlink ("tmp/original.jpg");