Как сохранить изображение в исходном размере?

#apache-flex

#apache-flex

Вопрос:

В моем приложении Flex я загружаю изображение в элемент управления Image. После загрузки изображения я могу применить фильтры, такие как преобразование цвета или оттенки серого и т.д., А Затем я хочу сохранить изображение с примененным фильтром. У меня возникли проблемы с сохранением изображения с примененными фильтрами. С помощью следующего кода изображение сохраняется без фильтров. Однако, если я использую

finalImagedata = ImageSnapshot.captureBitmapData(myImage);

Затем изображение сохраняется с примененными фильтрами, но с размером элемента управления изображением. Я хочу сохранить изображение с его исходным размером. Для ясности, если изображение имеет размер 1000 X 1000 пикселей и отображается в элементе управления изображением 300 X 300 пикселей, при сохранении я все равно хочу сохранить изображение с размером 1000 X 1000 пикселей. Как это сделать? Я также пытался получить BitmapData непосредственно из содержимого элемента управления изображением, как показано ниже, но, похоже, это не сработало. Ребята, кто-нибудь может помочь?

finalImagedata = Bitmap(myImage.content).BitmapData;

             var filtersArray:Array = new Array;
            private var finalImagedata:BitmapData;

            private function loadImage(url:String):void
            {
                var request:URLRequest = new URLRequest(url);

                var imageLoader:Loader = new Loader();
                imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, image_completeHanlder);
                imageLoader.load(request);
            }
            private function image_completeHanlder(event:Event):void
            {
                var bmd:BitmapData = Bitmap(event.currentTarget.content).bitmapData;
                var bmpMy:Bitmap = new Bitmap(bmd);
                myImage.data=bmpMy;

            }
            protected function button1_clickHandler(event:MouseEvent):void
            {
                loadImage("http://localhost/main/image.jpg"); 
            }

            protected function prepareFinalImage():void
            {
                finalImagedata = new BitmapData(myImage.content.width, myImage.content.height, true);
                finalImagedata.draw (myImage.content);
            }
            protected function btnSave_clickHandler(event:MouseEvent):void
            {
                prepareFinalImage();

                var encoder:Object = new Object();
                var defaultName:String;

                        var je:*;
                        je = new JPGEncoder(100);
                        encoder.encode = je.encode;
                        defaultName = "myImage.jpg";


                var imageBytes:ByteArray = encoder.encode(finalImagedata);
                var fr:FileReference = new FileReference();
                fr.save(imageBytes,defaultName);
            }


            protected function btnGrayScale_clickHandler(event:MouseEvent):void
            {
                var red:Number = 0.3086; // luminance contrast value for red
                var green:Number = 0.694; // luminance contrast value for green
                var blue:Number = 0.0820; // luminance contrast value for blue
                var cmf1:ColorMatrixFilter = new ColorMatrixFilter([red, green, blue, 0, 0, red, green, blue, 0, 0, red, green, blue, 0, 0, 0, 0, 0, 1, 0]);
                filtersArray.push(cmf1);
                myImage.filters = filtersArray;
            }
  

Комментарии:

1. Вы имеете в виду «как сохранить изображение в исходном размере»? Если нет, то вам следует избавиться от апострофа и вместо этого написать «как сохранить изображение в исходном размере»

Ответ №1:

Вы должны сохранить bitmapdata, полученные из Loader , как член класса:

 private var bmd:BitmapData;
[...]
private function image_completeHanlder(event:Event):void
{
    bmd = Bitmap(event.currentTarget.content).bitmapData;
    var bmpMy:Bitmap = new Bitmap(bmd);
    myImage.data=bmpMy;
}
  

и ваш prepareFinalImage метод должен полагаться на загруженные bitmapdata:

 protected function prepareFinalImage():void
{
    finalImagedata = new BitmapData(bmd.width, bmd.height, true);
    if (myImage.filters.length > 0)
        finalImagedata.applyFilter(bmd, 
            new Rectangle(0, 0, bmd.width, bmd.height), 
            new Point(0,0), myImage.filters[0] as BitmapFilter);
    if (myImage.filters.length > 1)
        for (var i:int = 1; i < myImage.filters.length; i  )
        {
            finalImagedata.applyFilter(finalImagedata, 
                new Rectangle(0, 0, bmd.width, bmd.height), 
                new Point(0,0), myImage.filters[i] as BitmapFilter);
        }
}
  

Таким образом, вы бы применили фильтры к BitmapData не к масштабируемому DisplayObject изображению.

Комментарии:

1. Возможно, я делаю что-то неправильно, но я продолжаю получать ошибку «TypeError: Ошибка # 2007: параметр filterObject должен быть ненулевым». когда я вызываю prepareFinalImage. Даже после применения фильтра.

2. Вы должны проверить, myImage.filters[i] as BitmapFilter является null ли приведение. Конечно, было бы лучше применить точные фильтры по порядку, в котором вы помещаете их в массив myImage.filters .

3. Возможно, в этом и была проблема. Приведение возвращает значение null. Я нашел обходной путь, чтобы применить фильтр непосредственно к объекту bitmapdata, загруженному загрузчиком, а затем отобразить его в элементе управления изображением. Таким образом, когда я хочу сохранить окончательное изображение, я могу сохранить его, используя эти bitmapdata. Однако я не уверен, что это правильный способ сделать это.