PDA

Просмотр полной версии : Ресайз изображения


Makkssimka
30.05.2013, 00:28
Доброго времени суток! Помогите разобраться, я получаю изображение в виде ByteArray, мне нужно сделать его ресайз, нашел пример как это делается через BitmapData, сделал следующую функцию:

function resize(images:ByteArray, h:int, w:int):ByteArray{
var loader:Loader = new Loader();
var newImg:BitmapData = new BitmapData(w, h);
loader.loadBytes(images);
newImg.draw(loader);
var newJpeg:ByteArray = new JPEGEncoder(90).encode(newImg);
return newJpeg;
}


И вызвал ее:

var image:ByteArray = imgList[i].img;
var img:ByteArray = resize(image, 200, 200);


Итог белый квадрат 200X200! Вы меня конечно извините может я что-то криво написал (я с AS на ВЫ), помогите разобраться где ошибки!

maincode
30.05.2013, 00:39
Прежде чем делать draw, необходимо дождаться окончания загрузки loader

yasha005
30.05.2013, 00:44
Ресайз изображения:
package
{
import flash.display.BitmapData;
import flash.geom.Matrix;

public class BitmapResize
{
private static const IDEAL_RESIZE_PERCENT:Number = .5;

public function BitmapResize()
{

}



public static function resizeImage(source:BitmapData, width:Number, height:Number, constrainProportions:Boolean = true):BitmapData
{
var scaleX:Number = width/source.width;
var scaleY:Number = height/source.height;
if (constrainProportions) {
if (scaleX > scaleY) scaleX = scaleY;
else scaleY = scaleX;
}

var bitmapData:BitmapData = source;

if (scaleX >= 1 && scaleY >= 1) {
bitmapData = new BitmapData(Math.ceil(source.width*scaleX), Math.ceil(source.height*scaleY), true, 0);
bitmapData.draw(source, new Matrix(scaleX, 0, 0, scaleY), null, null, null, true);
return bitmapData;
}

// scale it by the IDEAL for best quality
var nextScaleX:Number = scaleX;
var nextScaleY:Number = scaleY;
while (nextScaleX < 1) nextScaleX /= IDEAL_RESIZE_PERCENT;
while (nextScaleY < 1) nextScaleY /= IDEAL_RESIZE_PERCENT;

if (scaleX < IDEAL_RESIZE_PERCENT) nextScaleX *= IDEAL_RESIZE_PERCENT;
if (scaleY < IDEAL_RESIZE_PERCENT) nextScaleY *= IDEAL_RESIZE_PERCENT;

var temp:BitmapData = new BitmapData(bitmapData.width*nextScaleX, bitmapData.height*nextScaleY, true, 0);
temp.draw(bitmapData, new Matrix(nextScaleX, 0, 0, nextScaleY), null, null, null, true);
bitmapData = temp;

nextScaleX *= IDEAL_RESIZE_PERCENT;
nextScaleY *= IDEAL_RESIZE_PERCENT;

while (nextScaleX >= scaleX || nextScaleY >= scaleY) {
var actualScaleX:Number = nextScaleX >= scaleX ? IDEAL_RESIZE_PERCENT : 1;
var actualScaleY:Number = nextScaleY >= scaleY ? IDEAL_RESIZE_PERCENT : 1;
temp = new BitmapData(bitmapData.width*actualScaleX, bitmapData.height*actualScaleY, true, 0);
temp.draw(bitmapData, new Matrix(actualScaleX, 0, 0, actualScaleY), null, null, null, true);
bitmapData.dispose();
nextScaleX *= IDEAL_RESIZE_PERCENT;
nextScaleY *= IDEAL_RESIZE_PERCENT;
bitmapData = temp;
}

return bitmapData;
}



}
}

WisP
30.05.2013, 00:47
На лоадер нужно слушатель повесить и вытаскивать изображение через параметр content лоадера.

var loader:Loader;
var image:ByteArray = imgList[i].img;
var newImg:BitmapData = new BitmapData(w, h);
var img:ByteArray;
resize(image);

function resize(images:ByteArray):ByteArray
{
loader = new Loader();
loader.addEventListener(Event.COMPLETE, onLoaderComplete);
loader.loadBytes(images);
}
function onLoaderComplete(event:Event):void
{
newImg.draw(loader.content as Bitmap);
img = new JPEGEncoder(90).encode(newImg);
}

Код не проверял, но смысл должен быть ясен.

Makkssimka
30.05.2013, 16:11
WisP, Функция onLoaderComplete не выполняется?

Wolsh
30.05.2013, 17:19
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);

Makkssimka
30.05.2013, 18:09
trace(img) возвращает null

Final Hope
30.05.2013, 18:18
Вы же загружаете ByteArray, кажется? А потом вдруг делаете loader.content as Bitmap. Так, кажется, нельзя. Нет?

Makkssimka
30.05.2013, 18:21
Вот таким образом:


var loadIm:Loader;
resizIm(image);

function resizIm(im:ByteArray):void{
loadIm = new Loader();
loadIm.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
loadIm.loadBytes(im);
}

function onLoaderComplete(event:Event):void{
var newImg:BitmapData = new BitmapData(200, 200);
var img:ByteArray;
newImg.draw(loadIm.content as Bitmap);
img = new JPEGEncoder(90).encode(newImg);
trace (img);
}


trace выводит все нормально, но как img достать из функции?

Wolsh
30.05.2013, 19:46
Вызвать функцию, которая должна с ним работать, из того места в то ВРЕМЯ, когда он точно есть, то есть из onLoaderComplete.

Makkssimka
01.06.2013, 01:15
По чему в этом коде, при выборе нескольких изображений, сохраняется только одно:

for (var i:int = 0; i < imgList.length; i++) {
var image:ByteArray = imgList[i].img;
var imageName:String = imgList[i].name;
//Ресайз фото
var loadIm:Loader;
loadIm = new Loader();
loadIm.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
loadIm.loadBytes(image);

function onLoaderComplete(event:Event):void{
var newImg:BitmapData = new BitmapData(200, 200);
var img:ByteArray;
var vas:Bitmap = loadIm.content as Bitmap;
newImg.draw(vas);
img = new JPEGEncoder(90).encode(newImg);
upl(img); //Если сделать trace(img) то выводится два изображения
}
//конец
function upl(imag:ByteArray):void{ // Значит где-то здесь ошибка
var loader:MultipartURLLoader = new MultipartURLLoader;
loader.addVariable('imgName', imageName);
loader.addFile(imag, imageName, 'imgData', 'image/jpeg');
loader.load('http://upload.ro/up/bin-debug/upload.php');
loader.addEventListener(Event.COMPLETE, onCompletes);
}

WisP
01.06.2013, 01:29
Потому что ваш цикл (полагаю, что "}" потерялась перед объявлением первой функции) обрабатывается до того как происходит событие COMPLETE. И когда выполняется onLoaderComplete то цикл уже завершен. Следовательно будет сохранено первое изображение с именем imgList[1].name, а потом оно будет перезаписано вторым изображение с тем же именем.

Добавлено через 9 минут

var nameQuant:int;
for (var i:int = 0; i < imgList.length; i++)
{
var image:ByteArray = imgList[i].img;
var loadIm:Loader;
loadIm = new Loader();
loadIm.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
loadIm.loadBytes(image);
}

function onLoaderComplete(event:Event):void
{
var newImg:BitmapData = new BitmapData(200, 200);
var img:ByteArray;
var vas:Bitmap = loadIm.content as Bitmap;
newImg.draw(vas);
img = new JPEGEncoder(90).encode(newImg);
nameQuant++;
upl(img, "image_"+nameQuant);
}

function upl(imag:ByteArray, imgName:String):void
{
var loader:MultipartURLLoader = new MultipartURLLoader;
loader.addVariable('imgName', imgName);
loader.addFile(imag, imgName, 'imgData', 'image/jpeg');
loader.load('http://upload.ro/up/bin-debug/upload.php');
loader.addEventListener(Event.COMPLETE, onCompletes);
}

Makkssimka
01.06.2013, 01:39
И как это исправить?:D

Добавлено через 29 минут
WisP, таким образом проблема не решилась!

Добавлено через 38 часов 25 минут
Поменял код на следующий:

public var loadIm:Loader = new Loader();
public var imageName:String;
public function uploadImg(event:MouseEvent):void{
for (var i:int = 0; i < imgList.length; i++) {
var image:ByteArray = imgList[i].img;
imageName = imgList[i].name;
loadIm.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
loadIm.loadBytes(image);
}
}

public function onLoaderComplete(e:Event):void{
trace (vas); // Выдает только один объект Bitmap
var vas:Bitmap = loadIm.content as Bitmap;
var origBit:BitmapData = vas.bitmapData;
var soot:Number;
var scaleH:Number;
var scaleW:Number;
var scaleY:Number;
var scaleX:Number

if (origBit.height > origBit.width) {
soot = origBit.height/origBit.width;
scaleH = 1080/origBit.height;
scaleW = (1080/soot)/origBit.width;
scaleY = Number(scaleH.toFixed(3));
scaleX = Number(scaleW.toFixed(3));
}
else {
soot = origBit.width/origBit.height;
scaleW = 1920/origBit.width;
scaleH = (1920/soot)/origBit.height;
scaleY = Number(scaleH.toFixed(3));
scaleX = Number(scaleW.toFixed(3));
}

var newH:int = origBit.height*scaleH;
var newW:int = origBit.width*scaleW;


var scaleBit:BitmapData = new BitmapData(newW, newH, origBit.transparent);
var scaleMatrix:Matrix = new Matrix();
scaleMatrix.scale(scaleX, scaleY);

scaleBit.draw(origBit, scaleMatrix);

var img:ByteArray;
img = new JPEGEncoder(90).encode(scaleBit);
upl(img);
}

public function upl(imag:ByteArray):void{
var loader:MultipartURLLoader = new MultipartURLLoader;
loader.addVariable('imgName', imageName);
loader.addFile(imag, imageName, 'imgData', 'image/jpeg');
loader.load('http://upload.ro/up/bin-debug/upload.php');
loader.addEventListener(Event.COMPLETE, onCompletes);
}

public function onCompletes (event: Event):void {

}

Проблемы:
1. Все та же, сохраняется только последнее изображение из нескольких выбранных
2. При загрузке горизонтальных фото, по видимому во время их ресайза, опера подвисает(нет ответа) на несколько секунд, как это исправить?