Tworzenie jednakowych miniaturek w PHP

0

Na Allegro, na liscie aukcji, przy kazdej aukcji jest miniatura. Kazda miniatura ma te same rozmiary. Nawet jezeli jest to miniatura pionowa, to jest pomniejszana, a krawedzie (tlo) jest wypelniane kolorem bialym. Dzieki temu kazdy obrazek jest jednakowej wielkosci.

Moze ktos zarzucic skrawkiem kodu, ktory to realizuje? Przy pomocy biblioteki GD, bez zewnetrznych aplikacji. Wszystko co znajdowalem w necie do tej pory nie dziala poprawnie... tzn. dziala poprawnie, ale nie tak jak chce ;) Skaluje obrazek bazujac na wielkosci przez co, nie wszystkie miniatury maja te same rozmiary. A ja potrzebuje, aby kazda miniatura miala identyczne wymiary - 136x87 px.

0

Przeskaluj po wysokości i wklej na drugi obrazek o prawidłowych rozmiarach.
Jeśli miniaturka ma mieścić się w rozmiarze 150x100px (uproszczone), a twój obrazek ma 120x100px po przeskalowaniu według wysokości, to tworzysz obrazek 150x100 i wklejasz przeskalowany image w miejscu:

X: round((150-120)/2)
Y: 0

Dobra, z kodem trochę namotałem. Działająca wersja:

header('Content-Type: image/png'); //wysyłamy nagłówek

$tmp_image = imagecreatefrompng('test.png'); //miniaturka przeskalowana byle jak po wysokości
$final_image = imagecreatetruecolor($destx, $desty); //miniaturka o prawidłowym rozmiarze

$destx = 100; //wymarzona szerokość
$desty = 100; //wymarzona wysokość

$color = imagecolorallocate($final_image, 200, 200, 200); //alokujemy szary kolor
imagefill($final_image, 0, 0, $color); //malujemy cały finalny obraz na szaro

$sizex = imagesx($tmp_image); //pobieramy rozmiar x obrazka przeskalowanego byle jak
$sizey = imagesy($tmp_image); //pobieramy rozmiar y obrazka przeskalowanego byle jak

//na finalny obraz wklejamy ten, przeskalowany po wysokości, tak żeby znalazł się na środku
imagecopy($final_image, $tmp_image, round(($destx-$sizex)/2), 0, 0, 0, $sizex, $sizey);

imagepng($final_image); //wyświetlamy obraz

$tmp_image to obrazek przeskalowany po wysokości, z nieprawidłową szerokością.

Dla obrazka:
user image
<font size="1">Transparent PNG (80x100 px)</span>

Wynik to:
user image
<font size="1">PNG (100x100 px)</span>

Szara obwódka celowo, bo białej nie byłoby tu widać.
Przetestować sobie można tutaj.

Edit: I co, działa?

0

Dzieki wszystkim za odpowiedzi.
Teraz klient powiedzial ze wystarczy skalowanie okreslajac stala wielkosc szerokosci obrazka... :/ A to proste wiec zrobilem...

Ale mimo wszystko dzieki, przyda sie na przyszlosc...

0

Dopiero teraz przypomnialem sobie o Twoim kodzie :)
Wyprobowalem pod linkiem online ktory podales :)

Niestety nie dziala zbyt dobrze. Wyprobowalem dla obrazka 158x158. Chcialem, aby utworzyl mi miniature 100x100. Ucinal obrazek. Tak wiec wybralem, aby utworzyl miniature 200x200. Tu juz lepiej, lecz obrazek nie byl na srodku :)

Taka mala uwaga. Ale dobry punkt obrales, sprobuje zmodyfikowac Twoj kod, aby to dzialalo kompletnie :)

0

Bo ten obrazek musisz najpierw przeskalować jak jest za duzy. To nie jest kompletna funkcja.

0

Juz napisalem odpowiedni kod :)
Niedlugo wroce na SVN i dam tutaj linka, dla potomnych.

0

Dla potomnych: http://redmine.boduch.net/projects/coyote/repository/revisions/3312/entry/lib/image.class.php

Uzycie:


$image = new Image('foo.jpg');
$image->thumbail(100, 100);
$image->save('new_foo.jpg');
0

Mam nadzieje że nie będzie w złym tonie, ale zaproponuje moją ulubiona klasę (PHPThumb).

http://wiki.github.com/masterexploder/PHPThumb/basic-usage

<?php

require_once 'path/to/ThumbLib.inc.php';

try
{
     $thumb = PhpThumbFactory::create('/path/to/image.jpg');
}
catch (Exception $e)
{
     // handle error here however you'd like
}

$thumb->adaptiveResize(175, 175);
$thumb->show();

?>

0

Przecież to już jest napisane, a z PHPThumbem mogą być problemy licencyjne. Im mniej externalsów tym lepiej.

0

Po co się bawić w jakieś liby

/**
 * @author Keraj
 **/
function rescaleTo($input, $output)
{
	$ow = imagesx($output);
	$oh = imagesy($output);
	$offtop = 0;
	$offleft = 0;

	$scaler = $ow / $oh;
	
	$iw = imagesx($input);
	$ih = imagesy($input);
	
	$tw = $iw;
	$th = round($ih * $scaler);
	
	if($tw>$th)
	{
		$tw = $ow;
		$th = ($ih * $ow) / $iw;
		$offtop = round(($oh - $th) / 2);
	} else
	{
		$tw = ($iw * $oh) / $ih;
		$th = $oh;
		$offleft = round(($ow - $tw) / 2);
	}
	
	imagecopyresized  ($output, $input, $offleft  , $offtop  , 0  , 0  , $tw  , $th  , $iw  , $ih  );
}
// licencja: beerware

1 użytkowników online, w tym zalogowanych: 0, gości: 1