I have a very similar problem, but no solution:
I need to png encode an Image that is 130 x 30 but the byteArray it was created with is not long enough. I can see it right in front of me.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:
<mx:Script>
<![CDATA[
import mx.core.Application;
import mx.core.IFlexDisplayObject;
import mx.graphics.codec.PNGEncoder;
import mx.managers.PopUpManager;
private static var instance:Test = null;
private var strng:String ="";
private var png:ByteArray;
private var result:ByteArray;
public static function ready(str:String):void{
if (instance == null) instance = new Test();
instance.strng = str;
instance.show();
}
private function show() : void {
result = stringToByteArray(strng);
if (!this.isPopUp) {
setPopupHelpWindowStyle(this);
PopUpManager.addPopUp(this, Application.application as DisplayObject, false);
PopUpManager.centerPopUp(this);
}
img.load(result);
}
private static function setPopupHelpWindowStyle(ifdo:IFlexDisplayObject) : void {
var isc:IStyleClient = IFlexDisplayObject(ifdo) as IStyleClient;
isc.setStyle("modalTransparency", 1);
}
private static function stringToByteArray(str:String) : ByteArray {
var result:ByteArray = new ByteArray();
var i:int = 0;
while (i < str.length) {
result.writeByte(Number("0x" + str.substr(i, 2)));
i += 2;
}
return result;
}
public function encode():void{
var coder:PNGEncoder = new PNGEncoder;
instance.png = coder.encodeByteArray(instance.result, instance.img.width, instance.img.height);
}
]]>
</mx:Script>
<mx:Image
<mx:Button
</mx:TitleWindow>
When I try to encode it I get:
Error: Error #2030: End of file was encountered.
at flash.utils::ByteArray/readUnsignedInt()
I get an error because bArray is created from a string that is only 3540 characters long, which is only 1720 bytes. I can see the image, and it fills the entire box, but I do not know what type of alogorthm is used to expand the byteArray to fill it.
Is there a method to access the pixels of the image similar to the BitmapData function, where I can iterate through the pixels and read the bits directly from the display to build a new ByteArray? Or a way to make it into a bitmapdata object?
var bmd:BitmapData = ???;
var useableByteArray:ByteArray = new ByteArray();
for (var i:int =0; i < img.width; i++){
for (var j:int = 0; j < img.height; j++){
useableByteArray.writeByte(bmd.getPixel32(i, j));
}
}
Message was edited by: eboda_kcuf
Are you looking for BitmapData.draw()? Also, a common problem is that the ByteArray’s position is not set back to 0 after writing to it so subsequent reads start from the end.
The trouble seems to be that the byteArray used to create the component is to short, since the byte array for a png encoded image needs to be 4 * h * w bytes. The image appears on the screen, completely fills the 130 x 30 pixel area, and is held in:
<mx:Image
The byte array used to load the image is only 1,720 bytes, created from a string using the function above. I do not know what format the bytes are in, if they contain mime or header information or flood fills or anything. We can make the problem easier perhaps. I see :
on my display. The colored area is an image control I would like to png encode. The control is 130 x 30 created by calling img.load(byteArray) with a byte array that is 1720 bytes.
How can I png encode this image?
Also, If I try: newBitMapData.Draw(img) I get an empty area. Ideally I would simply like to read the area pixel by pixel and create a new byteArray that is the correct number of bytes in length. Can I gather pixel information directly somehow?
Message was edited by: eboda_kcuf added draw() info.
mx:image usually takes a JPG, PNG or GIF so it would be fewer bytes than 4 * h * w. The bitmapData will have 4 * h * w bytes.
That is the whole problem. I have a byte array, I need the bitmap of the rectangle it occupies....
Then use BItmapData.draw() on the Image?
Well, after many hours of experimentation and dickering, I managed to get the draw() method to work, somewhat.
( 'img' is the mx:Image that is loaded with the server supplied string after byte conversion
'img2' is a duplicate mx:Image 130 x 30 with no image loaded));
return ba;
}
The image does not appear in img2 however until I run the function a second time. Futher, the ba:ByteArray cannot be used to create a legitimate jpeg file, as it still produces an end of file error.
I have attempted to create a useful jpeg by extending the function:);
var arr:ByteArray = new ByteArray;
for (var i:int = 0; i < 130; i++) {
for (var j:int = 0; j < 30; j++){
var k:uint = bmp.bitmapData.getPixel32(i, j);
arr.writeUnsignedInt(k);
}
}
jenc = new JPEGEncoder;
myJpg = jenc.encodeByteArray(arr, 130, 30);
return ba;
}
However, the the byteArray produced by the JPEGEncoder still does not produce an acceptable image. I have reproduced the image by using a screen copy utility to "take a picture" of it. If I upload the file created this way it is acceptable. I am currently trying to discern the difference between the Encoder produced file and the disk copy and am now looking for a way to try and save the encoder produced file to disk to see if I can open it as a normal jpeg. I am sure there is a flash function to export the byteArray,** I am just a little exasperated with the endless difficulties I encounter with the flash platform.
Unfortunately I inherited a rather large project based on SDK 3.6 ( 72 mxml display files and over 300 as3 classes and auxillary files) and it is imperative that new functionality is incorporated in a timely manner without causing interuption of the useability.
The current problem is stretching into its second week and I still do not have a solution to what would be a very simple problem on most other platforms (i.e. to take an image that exists within its own container and upload it to a server in ANY standard format. bmp, jpg, gif or png would all be acceptable) As rediculous as it sounds, so far I have not been able to create a useable file within the flash environment from an existing image that I can not only see, but move or draw a frame around. In addition, the effort required to devlop a way to actually upload the file using internet standard multipart/form-data protocol further required that the payload be constructed one byte at a time then sent using urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
I realize that these may be things flash is not designed to do, but as technolgy and internet functionality changes software must adapt to match industry requirements or face extinction. Perhaps this is the reason the flash has been relegated to open source. Hopefully now it will develop in directions that will sustain its existance, but it will require effort that Adobe is apparently unwilling to invest.
Until things change I know now to never get involved with any flash-based project. It is impossible to justify the hours needed to find 'work-arounds' for tasks that should be straight-forward.
** This is a classic example of the difficulties I mentioned. Where is the 'saveToDisk' methiod? I sincerely hope it is not hidden in the same place as the 'uploadThePictureYouSee' method, because I STILL cannot find that one.....
Message was edited by: eboda_kcuf
Flash does have some idiosyncracies. Images are loaded asynchronously since they could be coming over a very slow network, so maybe the first image isn’t ready the first time you call encodeImage(). Are you waiting for the right event before running the function?
It looks like you have a legitimate JPEG byte array other wise img2 wouldn’t load it. So, assuming that, is the missing piece how to write that out to a server? See tella/CompareBitmap.as?view=log for how we write PNGs to a server.
Well, that all actually came out very well, thanx... I have decided to refactor the code in this project from sdk 3..6 to the latest update, mainly because I need to untangle the data from the display and to make the system more event driven rather than hard-wired through direct calls. The current system trips all over itself during periods of high server load, which then generates more lag because it takes the server much longer too deal with all the bad calls. As my user-base continues to increase it is becoming more critical. I am in a very competitive market, and I am reasonably sure that my competitors are not yet aware of the situation.
Admittedly I am far from an authority on best practice, but have enough common sense to see the problems. My concern now is to avoid common pitfalls and traps. I have gained a lot of insight and was extremely impressed by the link in the previous post. (I could not shake the impression of roaming the sacred catacombs that housed the Holy Grail, lol. This was reinforced by the obvious increase in khaos with each rising level, ending with pandemonium at the top...)
Unfortunately the repository no longer exists. Kinda makes me feel like Indian Jones or Lara Croft, about 10 minutes from the start of the story. I got a glimpse of the goal then an avalanche obscured the path.
So my current dilemma: A major part of the functionality of the application includes the acquisition of the image we just accomplished, and the subsequent uploading. This all works very smoothly now, so long as the user is there to click the button, but there are times when the user is not availible that this needs to happen. I understand the security causes for requiring the user to physically click a button to instigate a file transfer, but I must be missing something. Surely there must be a way to give 'pre-approval'?
As far as I can see, if the user wants to upload 50,000 files, they have to click 50,000 buttons, which is actually laughable. Last time I checked, security was not spelled 's-t-u-p-i-d-i-t-y'. It is really pretty basic, and I find it rather hard to believe that in all of history, Flex has never uploaded a picture without the user pushing a button....
So, there is surely a way for the user to allow the application to handle this in their absence???
North America
Europe, Middle East and Africa
Asia Pacific
South America