So I have been working the issue all day and I believe that I will have a tool ready by the end of the day tomorrow that will be able to make the toolchain work for images. It is a command line so you simply will drag your dummy object (or even your final object) and it will automatically find and convert all of the jpeg tags to lossless tags and save your swf with an appended _lossless to the filename. It took a lot of time because I had to do some modifications to the existing swf library for dotnet... and combined some code together. As I believe in sharing those changes I modified the DefineBitsJpeg2Tag.cs file of the SwfDotNet library as follows:
Code:
private void DecompileToStream(Stream stream)
{
BinaryWriter writer = new BinaryWriter(stream);
byte[] data = new byte[JpegData.Length];
Array.Copy(JpegData, data, JpegData.Length);
// first header
if (data[0] == 0xFF && data[1] == 0xD9 &&data[2] == 0xFF && data[3] == 0xD8)
{
byte[] copy = new byte[data.Length - 4];
Array.Copy(data, 4, copy, 0, data.Length - 4);
data = copy;
}
// cleans out bug markers in swf jpgs
int index = 2;
int len = data.Length;
while (index + 3 < len)
{
byte b0 = data[index];
if (b0 != 0xFF)
{
break;
}
if (data[index + 1] == 0xD9 && data[index + 2] == 0xFF && data[index + 3] == 0xD8)
{
// bingo
byte[] copy = new byte[data.Length - 4];
Array.Copy(data, 0, copy, 0, index);
Array.Copy(data, index + 4, copy, index, data.Length - index - 4);
data = copy;
break;
}
else
{
int tagLen = (data[index + 2] << 8) + data[index + 3] + 2;
index += tagLen;
}
}
writer.Write(data);
writer.Flush();
}
which is code I took from the Clean method of the DefineBitsTag.cs file of the SwfNet library (I determined that this method was what was causing my images to not decode correctly, not sure if it is a bug with the original library or the fact I am using a higher version of swf then the library was designed for)... and then... I modified the SwfHeader.cs MAX_VERSION constant in the SwfDotNet library to support a higher version (I used 8). It is in the latest build set to 7 which doesn't work for our purposes ._. .
Anyway that is what I have done so far with the following code:
Code:
static void Main(string[] args)
{
string filename = "C:\\UDK\\UDK-2011-05\\UDKGame\\Flash\\VectorMenuTut\\VectorMainMenu_Dummy.swf";
if (filename != "")
{
string name = Path.GetFileNameWithoutExtension(filename);
string outputFilename = "";
if (args.Length < 2)
{
outputFilename = Path.Combine(Path.GetDirectoryName(filename) , Path.GetFileNameWithoutExtension(filename) + "_Loseless"+Path.GetExtension(filename));
}
else
{
outputFilename = args[1];
}
Console.WriteLine("File: " + Path.GetFileNameWithoutExtension(filename));
Console.WriteLine("Output to: "+outputFilename);
SwfWriter swfWriter = new SwfWriter(outputFilename);
SwfReader swfReader = new SwfReader(filename);
Swf swf = swfReader.ReadSwf();
SwfHeader swfHeader = swf.Header;
Swf modifiedSwf = new Swf(swfHeader);
Console.WriteLine("Width: " + swfHeader.Width);
Console.WriteLine("Height: " + swfHeader.Height);
Console.WriteLine("FPS: " + swfHeader.Fps);
IEnumerator curTag = swf.Tags.GetEnumerator();
int a = 0;
while (curTag.MoveNext())
{
if (curTag.Current is DefineBitsJpeg3Tag)
{
Console.WriteLine("Found JPEG with alpha!");
DefineBitsJpeg3Tag jpegTag = curTag.Current as DefineBitsJpeg3Tag;
Image curImage = jpegTag.DecompileToImage();
Console.WriteLine("Image width: " + curImage.Width);
Console.WriteLine("Image height: " + curImage.Height);
a++;
}
else if (curTag.Current is DefineBitsJpeg2Tag)
{
DefineBitsJpeg2Tag jpegTag = curTag.Current as DefineBitsJpeg2Tag;
MemoryStream pngImageStream = new MemoryStream();
Image curImage = jpegTag.DecompileToImage();
curImage.Save(pngImageStream, ImageFormat.Bmp);
Image pngImage = Image.FromStream(pngImageStream);
pngImageStream.Close();
Console.WriteLine("Found JPEG!");
Console.WriteLine("Image width: " + curImage.Width);
Console.WriteLine("Image height: " + curImage.Height);
DefineBitsLossLessTag losslessTag = DefineBitsLossLessTag.FromImage(jpegTag.CharacterId,pngImage);
modifiedSwf.Tags.Add(losslessTag);
}
else
{
modifiedSwf.Tags.Add(curTag.Current as BaseTag);
}
}
swfWriter.Write(modifiedSwf);
swfWriter.Close();
swfReader.Close();
}
else
{
Console.WriteLine("Please supply a SWF on the command line! ");
}
Console.WriteLine();
Console.WriteLine();
Console.Write("Press any key to continue...");
Console.ReadKey();
}
}
Still has a ways to go, but it is progress
. The logic is the follows:
1. Open an SWF file that we want to convert and iterate all of the tags.
2. If we find a JPEG tag then we want to convert that to a lossless tag. (I still need to test and add alpha transparency stuff also).
3. Otherwise for all other tags we simply want to readd them to the output swf.
4. Save the newly converted SWF.
5. Profit!
And yes... I know none of this is obvious, it is a good bit of work, and I am more than likely insane... but! It is an interesting challenge
.
Bookmarks