2013-05-07 3 views
0

У меня есть скрипт Perl, который использует модуль Image :: Magick perl для обрезки существующего изображения из веб-формы (которая использует JCrop для подачи меня ширины, высоты, x, y). Поскольку обрезанное изображение будет использоваться в адаптивной среде разработки, я создаю несколько размеров изображения для использования на передней части веб-сайта. Размеры встроены в массив (как видно из кода ниже) и обрабатываются один за другим для создания каждого размера изображения.image :: Магический модуль perl - Множественные манипуляции с обрезкой/изменением размера из одного Read и One Write?

Как вы увидите из приведенного ниже кода, мне в конечном итоге нужно открыть изображение 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

+0

Я попробовал, что nwellnhof опубликовано ниже, что похоже на ваше предложение. Результаты публикуются ниже его записи в комментарии. –

ответ

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. У меня есть размеры, которые они должны быть записаны в файл журнала, и все они выглядят правильно. Какие-нибудь дальнейшие идеи? Я очень ценю вашу помощь. –

+2

Возможно, вам придется «поменять» изображение после обрезки с помощью '$ image-> Set (page => '0x0 + 0 + 0');'. – nwellnhof

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");