Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   Редактирование изображений перед отправкой (http://www.flasher.ru/forum/showthread.php?t=121263)

ix18 11.02.2009 17:30

Редактирование изображений перед отправкой
 
Добрый день!
Да, эта тема один раз неявно всплывала на просторах сего замечательного ресурса, однако есть желание расставить точки над i =)

Процесс следующий:
  1. Загрузка изображений с компьютера пользователя во флешку
  2. Простое редактирование изображений, из разряда масштабирование и поворот
  3. Загрузка изображений на сервер

Вариант с "просто загрузкой" отлично решает FileReference, который в 10й версии плеера обзавелся еще и [read-only] полем data, который позволяет посмотреть визуально, что же пользователь загрузил во флешку, перед отправкой на сервер.

Как-то вот так:
Код AS3:

image.source = fileReference.data;

* Однако, вся проблема в том, что поле-то это read-only :( Т.е., если сделать какую-то манипуляцию с картинкой, скажем, повернуть ее - то эти изменения никак не отразить в передаваемом файле.

* Собственно, как я понимаю, поля типа filter никак не влияют непосредственно на изображение, а только изменяют представление DisplayObject'а? Тогда какой подход выбрать к изменению изображения? И к его передаче на сервер =)

Foli 11.02.2009 18:15

А что у image.source не идёт получить что в него загружено?
Например в Delphi можно украсть всё с Canvas.
Конечно это рогатенько выглядит, но, как вариант.

etc 11.02.2009 18:39

Это ByteArray, вообще-то.

ix18 11.02.2009 20:55

Ну да, но проблема-то в том, как модифицировать изображения, подгруженные в клиент с помощью FileReference и измененную версию снова в него подсунуть, чтоб с помощью метода upload загрузить это хозяйство на сервер.
Тут я разделяю 2 концептуальных :) вопроса:
1. Как модифицировать изображение, имея его в массиве байтов.
2. Как модифицированное изображение "запихнуть" обратно в FileReference, чтобы отправить его.

По п.1. - есть в объекте Image, поле transform.matrix, однако, это влияет только на отображение, а не на саму картинку (т.е. последовательность байт)

По п.2. - если даже как-то изменить изображение, то непонятно, как его его загрузить в FileReference. Ведь, как уже говорилось, поле data - только на чтение.

etc 11.02.2009 20:56

data — это ссылка на ByteArray, вот его и изменяйте, как вам угодно.

Foli 11.02.2009 22:11

Цитата:

Сообщение от __etc
Это ByteArray, вообще-то.

Я не спорю. :umnik2:
Не довелось ещё пощупать, что и как. Но суть та же.
Получить байты и с ними работать.

Цитата:

Сообщение от ix18
Загрузка изображений на сервер.

А что на сервере? :cool:

Alex Lexcuk 12.02.2009 00:23

Код:

var fileRef:FileReference = new FileReference();
var date:Date = new Date();
fileRef.addEventListener(Event.SELECT, selectHandler);
fileRef.addEventListener(Event.COMPLETE, completeHandler);
try {
        var success:Boolean = fileRef.browse();
} catch (error:Error) {
        trace("Unable to browse for files.");
}
function selectHandler(event:Event):void {
        var request:URLRequest = new URLRequest("http://www.сайт.мой.ру/upload.php?="+date.getTime().toString());
        try {
                fileRef.upload(request);
        } catch (error:Error) {
                trace("Unable to upload file.");
        }
}
function completeHandler(event:Event):void {
        trace("uploaded");
        txt.text = "uploaded";
}

php
Код:

<?php
$MAXIMUM_FILESIZE = 1024 * 200; // 200KB
$MAXIMUM_FILE_COUNT = 10; // keep maximum 10 files on server
//echo exif_imagetype($_FILES['Filedata']);
if ($_FILES['Filedata']['size'] <= $MAXIMUM_FILESIZE)
{
        move_uploaded_file($_FILES['Filedata']['tmp_name'], "./images/".$_FILES['Filedata']['name']);
}

?>

Так же нужно создать в корневой папке сайта папку images
В эту папку будут сваливаться файлы

Не рекомендую использовать этот php скрипт, тк. он полностью губит ваш сайт
Ведь закачать можно любой файл, в том числе и php файл, нужно допилить php скрипт, что бы он принимал только файлы рисунков.

ix18 12.02.2009 02:47

Цитата:

Сообщение от Foli (Сообщение 797648)
Я не спорю. :umnik2:
Не довелось ещё пощупать, что и как. Но суть та же.
Получить байты и с ними работать.

А что на сервере? :cool:


Дык, круто :) Только 2 "но": это действительно ссылка, и в процессе дебага, действительно видно, что, скажем, применение метода clear, стирает этот массив. Но файл-то в итоге заливается! Изменения в нем - побоку. А задача именно - в изменении изображения перед отправкой. Как организовать просто отправку файла - это я знаю, спасибо =)

На сервере стоит PHP, написан скрипт, принимающий файлы, посредством POST-запроса. Но это не важно. Важно узнать как изменить изображение и отправить уже измененный экземпляр.

Alex Lexcuk, спасибо за код, но это уже давно реализовано, тема не о том :)

Почему-то мне кажется, что задача уже реализована не один раз... к сожалению, нигде не найти информации :(

GBee 12.02.2009 08:26

Вам же сказали про ByteArray, вот и думайте что файла не существует. Есть только ByteArray.

как сохранить bytearray flex php - это подсказанька :о))

Alex Lexcuk 12.02.2009 09:53

>>как сохранить bytearray flex php - это подсказанька :о))
Код:

//SaveByteArrayServerDoc
package {
        import flash.display.*;
        import flash.text.*;
        import flash.net.*;
        import flash.events.*;
        import flash.utils.*;
        public class SaveByteArrayServerDoc extends Sprite {
                private var ba:ByteArray,
                        fileName:String,
                        request:URLRequest,
                        loader: URLLoader;

                public function SaveByteArrayServerDoc():void {
                        ba = new ByteArray();
                        fileName = "text-file.txt";
                        request = new URLRequest(
                        "http://localhost/CONTENT_PATH/save-file.php?name="+fileName+"&d="+new Date().getTime());

                        ba.writeUTFBytes("йцукенгшщзхъфывапролджэ\ячсмитьбю.qwertyuiplkjhgfdsazxcvbnm,");
                       
                        request.data = ba;
                        request.method = URLRequestMethod.POST;
                        request.contentType = 'application/octet-stream';
                        loader = new URLLoader();
                        loader.addEventListener(Event.COMPLETE,completeHandler);
                        loader.load(request);

                }
                private function completeHandler(event:Event):void {
                        trace(loader.data);
                }
        }
}

/*
<?php
        //save-file.php
        $fileData = $GLOBALS[HTTP_RAW_POST_DATA];
        $fileName = ''.$_GET['name'].'.txt';
        $fp = fopen($fileName, "w");
        fwrite($fp,$fileData);
        fclose($fp);
        echo "file write - OK ".$fileName;
?>
*/


GBee 12.02.2009 10:12

Alex Lexcuk, зачем лишаете человека эстетического удовольствия от решения задачи?

P.S. Хотя задача все равно заключается в сохранении картинки, а не текста. :о)

etc 12.02.2009 12:36

Alex Lexcuk, вы вопрос в начале темы читали?

ix18 12.02.2009 20:35

Спасибо большое, видимо это то, что надо :)

Однако, есть один вопрос:

Код AS3:

 
public function SaveByteArrayServerDoc():void
{
        try
        {       
                fileName = fr.name;
                request = new URLRequest(
                "http://localhost:81/pic_test/process.php?name="+fileName);
 
                request.data = fr.data; // fr.data - ByteArray из FileReference
                request.method = URLRequestMethod.POST;
                request.contentType = "application/octet-stream";
 
                var loader:URLLoader = new URLLoader();
                loader.addEventListener(Event.COMPLETE,uploadCompleteDataHandler);
                loader.addEventListener(ProgressEvent.PROGRESS,progressHandler);
                loader.load(request);
        }
        catch (ioError:IOError)
        {
            trace("IOError.");
        }                               
        catch (error:Error)
        {
            trace("Some other error.");
        }
}

На строчке
Код AS3:

var loader:URLLoader = new URLLoader();

происходит следующая ошибка времени выполнения:

Код:

Error #2044: Необработанный ioError:. text=Error #2032: Ошибка потока. URL: http://localhost:81/pic_test/process.php?name=DSC01627.JPG
Специально обрамил весь участок кода метода SaveByteArrayServerDoc() в try-catch блок, но все равно то же самое сообщение :(

Alex Lexcuk 12.02.2009 21:19

Апач включен?
Попробуйте из браузера вызвать свой адрес
Код:

http://localhost:81/pic_test/process.php?name=DSC01627.JPG
по моему коду у себя запускаю из IE7
Код:

http://localhost/CONTENT_PATH/save-file.php?name=fileName+&d=12341234
Интернет эксплоер выдает
file write - OK fileName .txt
И создается пустой файл с именем fileName .txt в директории виртуального сервера
CONTENT_PATH. И еще небольшой прикол: записывать вот так DSC01627.JPG непосредственно, надо думать об модернизации php скрипта, что бы он принимал только JPG, а не допустим php файл. Запись постороннем лицом своего php файла это такая дыра, что ваш сайт может моментально стать порно сайтом. Целесообразно передавать имя файла без расширения, а расширение .jpg дописывать можно и php скриптом.

ix18 12.02.2009 22:57

Цитата:

Интернет эксплоер выдает
file write - OK fileName .txt
И создается пустой файл с именем fileName .txt в директории виртуального сервера
CONTENT_PATH.
Да, действительно - это я ступил :) В моем скрипте была маленькая ошибочка :)

Цитата:

И еще небольшой прикол: записывать вот так DSC01627.JPG непосредственно, надо думать об модернизации php скрипта, что бы он принимал только JPG, а не допустим php файл.
Абсолютно верно, скрипт будет учитывать возможные пути его некорректного использования и пресекать их.

Еще раз огромное спасибо!

Добавлено через 43 часа 45 минут
Теперь непосредственно о редактировании. Общая схема такая:
1. Создание объекта BitmapData из ByteArray.
2. Манипуляция (масштабирование, поворот).
3. Перевод из BitmapData в ByteArray.

Вот как-раз по этому пункту и есть главный вопрос. Использую JPEGEncoder, метод encode. Все работает, но скорость оставляет желать много лучшего.

Причем, недавно довелось мне увидеть и использовать новую версию загрузчика изображений в социальной сети "ВКонтакте". Там, сразу после загрузки изображения пользователя во флеш, происходит масштабирование - прямо на клиенте - и занимает оно ...... - не более 5 секунд!

Причем, пробовал туда подсунуть изображение ~5000*3000, обработка которого посредством моего скрипта занимает на 2*ядерном процессоре примерно полминуты. А тут - 3 сек. Странно.

Может это Алхимия? Вобщем, очень хотелось бы услышать ваши мнения, может есть готовые паттерны или компоненты для решения такой задачи.

etc 14.02.2009 19:16

А с чего вы взяли, что обработка происходит на клиентской стороне?


Часовой пояс GMT +4, время: 13:59.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.