|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Jan 2012
Сообщений: 5
|
При загрузке файлов перепутываются имена файлов
Здравствуйте.
Flash я начал изучать буквально меньше недели назад, поэтому прошу не пинать если что не так). Решил написать мультизагрузчик изображений на сервер с ресайзом на стороне клиента. Путём проб, ошибок, чтения мануалов и просмотра чужого кода написал код и всё вроде бы работает (фотографии ресайзятся и загружаются), но при загрузке большого количества файлов на сервер, у них(файлов) путаются названия. К примеру, выбираем файлы: 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg и загружаем их. На сервере изображение 5.jpg становится 4.jpg, а 1.jpg становится 2.jpg. Возникает ощущение, что эти перепутывания случайны, никакой закономерности не получается обнаружить. Если загружать 2-3 фотографии, то "перепутываний" названий не происходит. Сейчас попытаюсь объяснить сам код. По клику по кнопке вызывается метод browse() объекта FileReferenceList. Когда пользователь выбирает файлы, вызывается функция onSelect, в которой запускается цикл с количеством итераций, равным количеству файлов. На каждой итерации создаётся объект FileReference и у него вызывается метод load(), а также в массив ArrayCollection (предназначенный для хранения имён файлов) добавляется элемент с именем файла. На каждой итерации также создаётся addEventListener, который "слушает" загрузку файла во флэш и запускает функцию onLoad(), в которой вызывается метод loadBytes объекта Loader. Далее запускается функция resize() с параметрами BitmapData, размером и именем файла. Элемент с индексом 0 массива ArrayCollection удаляется. Функция resize(), помимо самого ресайза, выполняет и загрузку файлов на сервер. Вот и сам код: import mx.collections.ArrayCollection; import flash.net.URLLoader; import flash.net.URLRequest; import mx.graphics.codec.JPEGEncoder; private var fr:FileReferenceList = new FileReferenceList; private var reg:RegExp; private var fileNames:ArrayCollection = new ArrayCollection; //массив с названиями файлов. Каждый раз из него берётся элемент с индексом 0, затем этот элемент удаляется и так далее private function onClick():void { fr.browse(); fr.addEventListener(Event.SELECT, onSelect); } private function onSelect(e:Event):void { fr.removeEventListener(Event.SELECT, onSelect); for (var i:uint = 0; i < fr.fileList.length; i++) { reg = /\.\w+/; var fileName:String = fr.fileList[i].name.replace(reg,''); //убираем расширение файла fileNames.addItem(fileName); // в массив добавляется название файла var elem:Object = new Object; elem = FileReference(fr.fileList[i]); elem.cancel(); elem.load(); elem.addEventListener(Event.COMPLETE, onLoad); } } private function onLoad(e:Event):void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, afterLoad); loader.loadBytes(e.target.data); } private function afterLoad(e:Event):void { var bitmap:Bitmap = e.target.content; var bitmapData:BitmapData = bitmap.bitmapData; var fileName:String = fileNames[0]; //берётся название текущего файла в цикле fileNames.removeItemAt(0);//элемент с индексом 0 удаляется, а на его месте создаётся новый для следующего файла на следующей итерации resize(bitmapData, 200, fileName); resize(bitmapData, 600, fileName); } private function resize(bmd:BitmapData, size:Number, fileName:String):void { var scale:Number; var matrix:Matrix = new Matrix(); if (bmd.height > bmd.width) { scale = size / bmd.height; } else { scale = size / bmd.width; } matrix.scale(scale, scale); var minBmd:BitmapData = new BitmapData(bmd.width * scale, bmd.height * scale, true, 0x000000); minBmd.draw(bmd, matrix, null, null, null, true); var bmp:Bitmap = new Bitmap(minBmd, PixelSnapping.NEVER, true); var jpg:JPEGEncoder = new JPEGEncoder(); var myBytes:ByteArray = jpg.encode(bmp.bitmapData); var uploader:URLLoader = new URLLoader(); var type:String; if (size == 600) { type = "med"; } else { type = "min"; } var request:URLRequest = new URLRequest("uploadFile.php?name="+fileName+"&type="+type); var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); request.requestHeaders.push(header); request.method = URLRequestMethod.POST; request.data = myBytes; uploader.load(request); } Возникает впечатление, что цикл переходит на следующую итерацию, не дождавшись, когда выполнятся все функции, запускаемые по elem.addEventListener(Event.COMPLETE, onLoad);, отсюда и путаница в названиях файлов. В чём может быть проблема? Буду благодарен за любые мысли. Вместо массива fileNames:ArrayCollection = new ArrayCollection раньше заводил строковую переменную fileName:String, но во всех итерациях цикла эта переменная принимала одно значение. Последний раз редактировалось Sergey_S; 15.01.2012 в 16:42. Причина: Отредактировал отступы кода |
|
|||||
По всей видимости у вас не успевает загрузиться предыдущее изображение и вы начинаете грузить следующее.
Воспользуйтесь рекурсией. Как только происходит комплит, начинайте грузить следующее изображение, если его номер не превышает общего колличества. В вашем onSelect запускайте загрузку одного изображения. Слушайте COMPLETE. Как только он произойдёт - начинайте грузить следующее изображение, где опять же начинайте слушать COMPLETE. Цитата:
И ещё по теме с JPEG. Это работает быстрее, чем использованный вами вариант. Спасибо говорить BlooDHounD
__________________
ЛОДКИ Последний раз редактировалось FlashRus; 15.01.2012 в 16:57. |
|
|||||
Регистрация: Jan 2012
Сообщений: 5
|
Спасибо большое за ответ! Сейчас попробую реализовать.
upd. Всё, сделал. Также прикрутил кодировщик jpeg blooddy_crypto.swc, действительно, работает заметно быстрее стандартного. Последний раз редактировалось Sergey_S; 15.01.2012 в 19:35. |
|
|||||
Регистрация: Nov 2010
Сообщений: 150
|
А смысл ждать загрузки предыдущего файла чтобы загрузить следующий, как то не по христиански. А если он вообще не загрузится (собака кабеля погрызла), как минимум обработку ошибок добавить надо. А вообще загрузку по хорошему нужно делать параллельно (в этом и смысл слова "мультизагрузчик"). К примеру, Loader вынести в отдельный класс, в котором будет храниться имя файла, тогда по завершению загрузки будет известно какому файлу соответствуют загруженные данные.
Последний раз редактировалось Stitch512; 16.01.2012 в 00:24. |
|
|||||
Регистрация: Jan 2012
Сообщений: 5
|
Stitch512, у меня стояла цель сделать загрузчик, как ВКонтакте (там же загрузчик последовательно загружает?), чтобы можно было выбрать сразу несколько файлов и последовательно их загрузить. Важна возможность для пользователя редактировать свойства первой и последующих фотографий, пока загружаются остальные. Обработку ошибок само собой добавлю, когда буду запускать проект.
Кстати, ещё вопрос: оправдано ли я поступил, сделав ресайз на стороне клиента для среднего и малого размера? Ведь в этом случае получается, что для одной фотки придётся сделать три аплода (оригинал фото, средняя и миниатюра). Плюс этого решения в том, что серверу не приходится нагружаться для ресайза. Минус - большой трафик. Можно было бы сделать загрузку сразу оригинала и последующий ресайз уже на сервере, однако это нехило нагружало бы сервер (фотографии будут загружать до 4МБ). В данном случае плюс как раз меньший трафик. Я так понимаю тот же ВКонтакте использует первый вариант (ресайзит все варианты фото на клиенте и загружает уже готовые на сервер). Я прав? Последний раз редактировалось Sergey_S; 17.01.2012 в 13:18. |
|
|||||
Banned
[+1 05.11.11]
[+1 09.08.11] Регистрация: Jan 2010
Адрес: РФ. Кемеровская область
Сообщений: 3,243
|
Цитата:
А если клиент загрузит какую-нибудь вообще огромную пикчу? Так будет и трафик большой и нагрузка сервера. Конечно это все лучше делать на машине пользователя. Так по крайней мере уже будут примерно известны размеры всех трех картинок в сумме. И трафик, в большинстве случаев, как раз будет меньше. |
Часовой пояс GMT +4, время: 13:31. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|