PDA

Просмотр полной версии : Как сблендить 2 изображения со сдвигом?


greeka
16.06.2012, 17:10
Всем привет,

Есть такая задача - нужно наложить одно изображение на другое с перемножением (BlendMode.MULTIPLY) и установить его в указанные координаты.
Делаю так:


//Основное изображение
var currentImage:BitmapData = new BitmapData(width, height, false, 0xaaffaa);

далее по загрузке внешнего изображения, которое наложится поверх:


var image:Bitmap = Bitmap(Loader(event.target.loader).content);
var matrix:Matrix = new Matrix();
matrix.ty = 10; //тут вроде как должно сдвинуться вниз на 10 точек
currentImage.draw(image.bitmapData, matrix, null, BlendMode.MULTIPLY, new Rectangle(0, 0, image.bitmapData.width, image.bitmapData.height));

В результате накладываемое изображение обрезается сверху на 10 точек, но не сдвигается, а судя по мануалу: http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html должно быть сдвинуто. В другие методы наложения нельзя передать BlendMode.
Как быть?

samana
16.06.2012, 17:20
Если я правильно понял, то тогда ваше первое изображение (currentImage), должно быть на 10 px больше в низ, чем надо. Ведь вы же потом сами пытаетесь отрисовать другую картинку в нём, ниже на 10 px.
Ведь у битмапдаты фиксированные размеры, и она не станет ни больше ни меньше, что бы в неё не рисовали.

greeka
16.06.2012, 17:27
Если я правильно понял, то тогда ваше первое изображение (currentImage), должно быть на 10 px больше в низ, чем надо. Ведь вы же потом сами пытаетесь отрисовать другую картинку в нём, ниже на 10 px.
Ведь у битмапдаты фиксированные размеры, и она не станет ни больше ни меньше, что бы в неё не рисовали.

Не совсем так. Вот что получается без изменения матрицы:
28103

А вот это при matrix.ty=10
28102
Фактически оно сдвинулось на 10 точек ниже, но и обрезало его.
Размер исходного изображения 512*512, накладываемого: 325*98

silin
16.06.2012, 18:49
не удалось воспроизвести трабл, можешь соорудить 'живой' примерчик?
подозрение, что непонятки с clipRect в draw, он зачем здесь вообще если это image.bitmapData.rect ?

greeka
16.06.2012, 21:09
Я тут мистику обнаружил... Даже не знаю что и сказать, вот смотрите сами:
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.net.URLRequest;

[SWF(backgroundColor="#000000", frameRate="60", width="512", height="512")]
public class ImageTest extends Sprite
{
private var currentImage:BitmapData;

[Embed(source="b945c48cce2e_best.jpg")]
private var testPicture:Class;

public function ImageTest()
{
currentImage = new BitmapData(512, 512, false, 0xaaffaa);

var bm:Bitmap = new Bitmap(currentImage);
bm.x = bm.y = 0;
addChild(bm);

//Работающий пример
/*
var pic:Bitmap = new testPicture();
var matrix:Matrix = new Matrix();
matrix.translate(50, 50);
currentImage.draw(pic.bitmapData, matrix, null, BlendMode.MULTIPLY);
*/

//Мистический пример

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
var url:String = 'http://www.google.com.ua/images/srpr/logo3w.png'; //Да простит меня гугл
var request:URLRequest = new URLRequest(url);
loader.load(request);

}

private function completeHandler (event:Event):void {

/*var pic:Bitmap = new testPicture();
var matrix:Matrix = new Matrix();
matrix.translate(10, 0);
currentImage.draw(pic.bitmapData, matrix, null, BlendMode.MULTIPLY);

return;*/

var image:Bitmap = Bitmap(Loader(event.target.loader).content);
var matrix:Matrix = new Matrix();
matrix.translate(10, 0);
currentImage.draw(image.bitmapData, matrix, null, BlendMode.MULTIPLY);
}
}
}
Сейчас работает мистический код, который обрезает картинку. Если его закоментить и раскоментить "работающий пример", то все понятное дело работает. Так же в completeHandler для наглядности продублирован "работающий" код, который не работает (обрезается).

-De-
16.06.2012, 21:43
Использовать сторонние изображения не так просто. Либо сервер вам разрешает их грузить (а гугол не разрешает), либо это сервер (т.е. домен) с которого загружена флэшка (тогда автоматом разрешает), либо вы можете только добавлять их на сцену. Менять - нельзя. Возможно связанно с этим. Т.к. система отслеживания чо кому можно достаточно сложна - она может давать такие вот сторонние эффекты.

greeka
16.06.2012, 21:59
Дело не в этом, все грузится нормально. В эвентере не отрисовывались даже заэмбеженные изображения. Вот это меня смущало.
Трабла была именно в выводе изображения.
Поставил
currentImage.lock();
currentImage.draw(image.bitmapData, matrix, null, BlendMode.MULTIPLY);
currentImage.unlock();
все заработало с любым изображением и в любом месте. Но блин, мистическая штука.

silin
16.06.2012, 22:31
думаю, что дело именно в этом: загрузит и покажет, но доступа к bimapData без разрешения не будет (dimarik подробно писал об этом http://www.flasher.ru/forum/blog.php?b=208 )
к слову, непонятно зачем в draw именно image.bitmapData, почему не сам лоадер ?
такой вот вариант работает
private function completeHandler (event:Event):void {

var matrix:Matrix = new Matrix();
matrix.translate(50, 0);
currentImage.draw(event.target.loader, matrix, null, BlendMode.MULTIPLY);

}

greeka
17.06.2012, 01:24
image.bitmapData вобщем-то не нужен, это я экспериментировал.
По проблеме - оно либо работает либо нет, но чтоб часть пикселей не работала (не было доступа, например), а другая часть работала - то такого не бывает.
Кроме того, это у меня в билдере такое поведение, а там же более лояльные политики.
ваш вариант с event.target.loader работает.