Zobrazení obrázku po uploadu bez uložení na server
- kovarik.t
- Člen | 18
Ahoj, chtěl bych udělat upload pomocí nette a oříznutí obrázku pomocí
javascriptu Až sem nejlépe bez nutnosti uložit ho na serveru. K tomu
potřebuji zobrazit obrázek po uploadu ale nějak se mi nedaří.
Zkusí mě někdo nasměrovat?
public $img
protected function createComponentUploadForm($name)
{
$uploadForm = new Form($this, $name);
$uploadForm->addUpload('img', 'Obrázek')
->addRule(Form::IMAGE, 'Avatar musí být JPEG, PNG nebo GIF.')
->addRule(Form::MAX_FILE_SIZE, 'Maximální velikost souboru je 500 kB.', 500 * 1024 /* v bytech */);
$uploadForm->addSubmit('upload', 'Nahraj')
->setAttribute('class', 'btn btn-primary')
->onClick[] = callback($this, 'upload');
return $uploadForm;
}
public function upload($button)
{
$values = $button->getForm()->getValues(TRUE);
$this->img = $values['img']->toImage()->toString(IMAGETYPE_JPEG, NULL);
}
<img src="{$img}"> //zkoušel jsem i helper |dataStream
Editoval kovarik.t (18. 1. 2014 11:31)
- Majkl578
- Moderator | 1364
Datastream by měl fungovat, akorát v IE<=8 je omezen na 32kB.
Předáváš proměnnou do šablony? V uvedeném kódu to neděláš. (Mělo by
se tak dít buď v té metodě upload nebo někde v render fázi, v action by
se předalo NULL
).
Jinak obrázek můžeš zobrazit i před uploadem pomocí FileReaderu, který je součástí HTML5 File API.
- kovarik.t
- Člen | 18
Majkl578 napsal(a):
Jinak obrázek můžeš zobrazit i před uploadem pomocí FileReaderu, který je součástí HTML5 File API.
Díky za tip, HTML5 File API zafungovalo skvěle. Přikládám komponentu kdyby to někoho zajímalo. Ořez je provedenej pomocí imgAreaSelect
class AvatarControl extends Control
{
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/AvatarControl.latte');
//$template->form = $this->getComponent('uploadForm');
$template->render();
}
protected function createComponentUploadForm($name)
{
$uploadForm = new Form($this, $name);
$uploadForm->addUpload('img', 'Obrázek')
->setAttribute('onchange', 'PreviewImage();')
->addRule(Form::IMAGE, 'Avatar musí být JPEG, PNG nebo GIF.');
$uploadForm->addHidden('left', '');
$uploadForm->addHidden('top', '');
$uploadForm->addHidden('selectionWidth', '');
$uploadForm->addHidden('selectionHeight', '');
$uploadForm->addHidden('imgWidth', '');
$uploadForm->addHidden('imgHeight', '');
$uploadForm->addSubmit('upload', 'Nahraj')
->setAttribute('class', 'btn btn-primary')
->onClick[] = callback($this, 'upload');
return $uploadForm;
}
public function upload($button)
{
$values = $button->getForm()->getValues(TRUE);
dump($values);
if ($values['img']->isOk())
{
$image = Image::fromFile($values["img"]);
if($values['imgWidth'])
{
$z = $image->getWidth() / $values['imgWidth']; // koeficient zmenšení
$left = $values['left'] * $z;
$top = $values['top'] * $z;
$width = $values['selectionWidth'] * $z;
$height = $values['selectionHeight'] * $z;
}
else
{
if($image->getWidth() > $image->getHeight()) //obrázek na šířku
{
$left = ($image->getWidth() - $image->getHeight()) /2;
$top = 0;
$width = $image->getHeight(); //aspect ratio 1:1
$height = $image->getHeight();
}
else //obrázek na výšku nebo 1:1
{
$left = 0;
$top = ($image->getHeight() - $image->getWidth()) /2;
$width = $image->getWidth();
$height = $image->getWidth(); //aspect ratio 1:1
}
}
$path = "c:/xampp/htdocs/avatar-component-nette/www/userfiles/images/";
$name = uniqid();
$image->crop($left, $top, $width, $height);
//$image->sharpen();
$image->resize(150, 150);
$image->save($path . $name.".jpg", 80, Image::JPEG); // JPEG, kvalita 80%
$this->flashMessage('Profilový obrázek byl úspěšně nahrán.', 'success');
}
else
{
$this->flashMessage('Nepovedlo se nahrát profilový obrázek.', 'warning');
}
}
}
<style>
#uploadPreview {
max-height: 500px;
max-width: 100%;
}
</style>
<img id="uploadPreview" />
{form uploadForm}
{input img}{input upload}
{/form}
<script type="text/javascript">
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("frm-avatar-uploadForm-img").files[0]);
oFReader.onload = function (oFREvent) {
document.getElementById("uploadPreview").src = oFREvent.target.result;
};
};
$(document).ready(function () {
$('#uploadPreview').imgAreaSelect({
aspectRatio: '1:1',
handles: true,
onSelectEnd: function (img, selection) {
$('input[name="left"]').val(selection.x1); // koordináty zleva
$('input[name="top"]').val(selection.y1); //koordynáty shora
$('input[name="selectionWidth"]').val(selection.width); //šířka výběru
$('input[name="selectionHeight"]').val(selection.height); //výška výběru
$('input[name="imgWidth"]').val(img.width); //šířka obrázku v prohlížeči
$('input[name="imgHeight"]').val(img.height); //výška obrázku v prohlížeči
}
});
});
</script>
Editoval kovarik.t (18. 1. 2014 22:49)
- mpis
- Člen | 65
To je přesně to, co hledám. Ale nemůžu to rozchodit.
Předpokládám, že ten script má zobrazit obrázek na stránce ještě před
odesláním.
A to se mi právě nezobrazí.
Nevím, kde bych mohl dělat chybu. Opsal jsem to odtud přesně.
Mně by stačilo jen pouhé zobrazení načteného obrázku bez
ořezávání.
- honos
- Člen | 109
mpis napsal(a):
…
prohlizec nepodporuje html5?
EDIT:
clanek v eng ale srozumitelny a obsirny a pisecek –
pohraj si
Editoval honos (31. 1. 2014 0:27)
- Majkl578
- Moderator | 1364
V kódu od @kovarik.t by bylo určitě žádoucí
přidat kontrolu, zda prohlížeč File API vůbec podporuje. Tedy řekněme
obalit podmínkou if (window.FileReader) { ... }
.
Přidám kousíček kódu, který jsem použil před pár dny, kdy jsem dělal
právě client-side náhled obrázku, spíš jako inspiraci:
// file upload image preview before submit
if (window.FileReader) {
$body.on('change', FORM_SELECTOR + ' .upload-picture input[type=file]', function () {
var $this = $(this);
var $previewContainer = $this.parents('.some-form-wrapper').find('.upload-picture-preview');
var reader = new FileReader();
reader.onloadend = function () {
var $img = $previewContainer.children('img');
if (!$img.length) {
$img = $('<img>');
$img.appendTo($previewContainer);
}
$img.prop('src', reader.result);
};
reader.readAsDataURL(this.files[0]);
});
}