package com.webork.createcomic.util;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Vector;
import com.jswiff.SWFWriter;
import com.jswiff.SWFDocument;
import com.jswiff.swfrecords.AlphaBitmapData;
import com.jswiff.swfrecords.FillStyle;
import com.jswiff.swfrecords.FillStyleArray;
import com.jswiff.swfrecords.LineStyleArray;
import com.jswiff.swfrecords.RGB;
import com.jswiff.swfrecords.RGBA;
import com.jswiff.swfrecords.Rect;
import com.jswiff.swfrecords.Matrix;
import com.jswiff.swfrecords.ShapeRecord;
import com.jswiff.swfrecords.ShapeWithStyle;
import com.jswiff.swfrecords.SoundInfo;
import com.jswiff.swfrecords.StraightEdgeRecord;
import com.jswiff.swfrecords.StyleChangeRecord;
import com.jswiff.swfrecords.tags.DefineBitsJPEG2;
import com.jswiff.swfrecords.tags.DefineBitsLossless2;
import com.jswiff.swfrecords.tags.DefineEditText;
import com.jswiff.swfrecords.tags.DefineFont2;
import com.jswiff.swfrecords.tags.DefineShape;
import com.jswiff.swfrecords.tags.DefineSound;
import com.jswiff.swfrecords.tags.DefineSprite;
import com.jswiff.swfrecords.tags.DefinitionTag;
import com.jswiff.swfrecords.tags.PlaceObject2;
import com.jswiff.swfrecords.tags.RemoveObject2;
import com.jswiff.swfrecords.tags.ShowFrame;
import com.jswiff.swfrecords.tags.StartSound;
import com.jswiff.util.ImageUtilities;
import com.jswiff.xml.XMLReader;
import com.jswiff.xml.XMLWriter;
import com.webork.createcomic.util.gif.*;
/**
* explain<br>
* encapsulation apart of JSwiff in order to use easy<br><br>
*
* how to use<br>
* // first frame, add sound<br>
* FileInputStream fis = new FileInputStream(".../one.mp3");<br>
* byte[] soundContentBytes = new byte[fis.available()];<br>
* fis.read(soundContentBytes);<br>
* int soundId1 = swfUtil.addSoundTag(document, soundContentBytes, SWFUtil.SOUND_TYPE.MP3);<br>
* swfUtil.addStartSoundTag(document, soundId1);<br><br>
*
* // first frame, add sound<br>
* fis = new FileInputStream(".../two.mp3");<br>
* soundContentBytes = new byte[fis.available()];<br>
* fis.read(soundContentBytes);<br>
* int soundId2 = swfUtil.addSoundTag(document, soundContentBytes, SWFUtil.SOUND_TYPE.MP3);<br><br>
*
* // first frame, add pic<br>
* fis = new FileInputStream(".../pic1.jpg");<br>
* byte[] byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int picId1 = swfUtil.addJpegTag(document, byteArray);<br><br>
*
* fis = new FileInputStream(".../pic2.jpg");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int picId2 = swfUtil.addJpegTag(document, byteArray);<br><br>
*
* // first frame, add gif<br>
* fis = new FileInputStream(".../gif1.gif");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int gifId1 = swfUtil.addGifSpriteTag(document, byteArray);<br><br>
*
* // display<br>
* swfUtil.addDisplayGifSpriteTag(document, gifId1, 3, 2000, 2000);<br>
* swfUtil.addDisplayGifSpriteTag(document, gifId1, 4, 500, 500);<br>
* swfUtil.addPlaceObject2Tag(document, picId1, 1, 1000, 1000);<br>
* swfUtil.addPlaceObject2Tag(document, picId2, 2, 150, 150);<br><br>
*
* for (int i = 0; i < 25; i++) swfUtil.addShowFrameTag(document);<br><br>
*
* swfUtil.addRemoveGifSpriteTag(document, 4);<br><br>
*
* for (int i = 0; i < 25; i++) swfUtil.addShowFrameTag(document);<br><br>
*
* // disable<br>
* swfUtil.addRemoveObject2Tag(document, 1);<br>
* swfUtil.addRemoveObject2Tag(document, 2);<br>
* swfUtil.addRemoveGifSpriteTag(document, 3);<br>
* swfUtil.addStopSoundTag(document, soundId1);<br><br>
*
* // second frame, add pic<br>
* fis = new FileInputStream(".../pic3.png");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int picId3 = swfUtil.addPngTag(document, byteArray);<br><br>
*
* // second frame, add gif<br>
* fis = new FileInputStream(".../gif2.gif");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int gifId2 = swfUtil.addGifSpriteTag(document, byteArray);<br><br>
*
* swfUtil.addDisplayGifSpriteTag(document, gifId2, 2, 4000, 4000);<br>
* swfUtil.addStartSoundTag(document, soundId2);<br>
* swfUtil.addPlaceObject2Tag(document, picId3, 1, 0, 0);<br><br>
*
* for (int i = 0; i < 10; i++) swfUtil.addShowFrameTag(document);<br><br>
*
* swfUtil.addRemoveObject2Tag(document, 1);<br>
* swfUtil.addRemoveGifSpriteTag(document, 2);<br><br>
*
* // third frame, add text<br>
* Color color = new Color(255, 0, 0);<br>
* int textId = swfUtil.addTextTag(document, "hi, it's ok.", "Arial", color, 400);<br>
* swfUtil.addPlaceObject2Tag(document, textId, 1, 500, 500);<br><br>
*
* fis = new FileInputStream(".../pic4.jpg");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int picId4 = swfUtil.addJpegTag(document, byteArray);<br><br>
*
* // third frame, add gif<br>
* fis = new FileInputStream(".../gif3.gif");<br>
* byteArray = new byte[fis.available()];<br>
* fis.read(byteArray);<br>
* int gifId3 = swfUtil.addGifSpriteTag(document, byteArray);<br><br>
*
* swfUtil.addDisplayGifSpriteTag(document, gifId3, 3, 2000, 2000);<br>
* swfUtil.addPlaceObject2Tag(document, picId4, 2, 600, 600);<br>
* swfUtil.addPlaceObject2Tag(document, picId3, 4, 3000, 3000);<br><br>
*
* for (int i = 0; i < 20; i++) swfUtil.addShowFrameTag(document);<br><br>
*
* swfUtil.addRemoveObject2Tag(document, 1);<br>
* swfUtil.addRemoveObject2Tag(document, 2);<br>
* swfUtil.addRemoveGifSpriteTag(document, 3);<br>
* swfUtil.addRemoveObject2Tag(document, 4);<br>
* swfUtil.addStopSoundTag(document, soundId2);<br><br>
*
* swfUtil.writeDocument(document, ".../test.swf");<br>
* FileOutputStream fos = new FileOutputStream(".../test.swf.xml");<br>
* swfUtil.convertSWFToXml(document, fos);<br>
*/
public class SWFUtil {
/**
* write flash doc
* @param document in flash obj
* @param outName in file path
*/
public void writeDocument(SWFDocument document/*in*/, String outName/*in*/) {
try {
SWFWriter writer;
writer = new SWFWriter(document, new FileOutputStream(outName));
writer.write();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* convert xml to flash
* @param fileInName in xml file name
* @param fileOutName in swf file name
*/
public void convertXmlToSWF(String fileInName/*in*/, String fileOutName/*in*/) {
try {
XMLReader xmlReader = new XMLReader(new FileInputStream(fileInName));
writeDocument(xmlReader.getDocument(), fileOutName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* convert flash to xml
* @param document in falsh obj
* @param fos in xml file path
*/
public void convertSWFToXml(SWFDocument document/*in*/, FileOutputStream fos/*in*/) {
try {
XMLWriter writer = new XMLWriter(document);
writer.write(fos, true);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* convert flash frame
* @param playTime in display tiems
* @return ??
*/
public int convertTimeToFrames(int playTime/*in*/) {
return playTime * playRate / MILLISECOND;
}
/**
* set flash bgcolor
* @param document in falsh obj
* @param color in color
*/
public void setBackgroundColor(SWFDocument document/*in*/, Color color/*in*/) {
document.setBackgroundColor(
new RGB(color.getRed(), color.getGreen(), color.getBlue()));
}
/**
* set flash bgsize
* @param document in falsh obj
* @param xLength in x length
* @param yLength in y length
*/
public void setBackgroundSize(SWFDocument document/*in*/,
int xLength/*in*/, int yLength/*in*/) {
if (0 < xLength && 0 < yLength) {
document.setFrameSize(new Rect(0, xLength*20, 0, yLength*20));
}
}
/**
* display
* @param document in falsh obj
* @param characterId in pic ID
* @param depth in depth
* @param x in x coordinate
* @param y in y coordinate
*/
public void addPlaceObject2Tag(SWFDocument document/*in*/, int characterId/*in*/,
int depth/*in*/, int x/*in*/, int y/*in*/) {
PlaceObject2 placeObject2 = new PlaceObject2(depth);
placeObject2.setCharacterId(characterId);
placeObject2.setMatrix(new Matrix(x, y));
document.addTag(placeObject2);
}
/**
* disable
* @param document in falsh obj
* @param depth in depth
*/
public void addRemoveObject2Tag(SWFDocument document/*in*/, int depth/*in*/) {
document.addTag(new RemoveObject2(depth));
}
/**
* show frame
* @param document in falsh obj
*/
public void addShowFrameTag(SWFDocument document/*in*/) {
document.addTag(new ShowFrame());
}
/**
* add sound, support mp3,wav
* @param document in falsh obj
* @param soundContentBytes in content
* @param soundType in
*/
public int addSoundTag(SWFDocument document/*in*/, byte[] soundContentBytes/*in*/,
SOUND_TYPE soundType/*in*/) {
int sound_id = document.getNewCharacterId();
DefineSound defineSound = null;
if (SOUND_TYPE.MP3 == soundType) {
long lengthMSEL = SoundUtil.getSoundLength(soundContentBytes, SoundUtil.SOUND_TYPE.MP3);
long frequency = SoundUtil.getSoundFrequency(soundContentBytes, SoundUtil.SOUND_TYPE.MP3);
long sampleCount = (lengthMSEL * frequency) / MILLISECOND;
if (4 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_MP3, DefineSound.RATE_44000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (2 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_MP3, DefineSound.RATE_22000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (1 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_MP3, DefineSound.RATE_11000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (0 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_MP3, DefineSound.RATE_5500_HZ,
true, false, sampleCount, soundContentBytes);
} else {
return -1;
}
} else if (SOUND_TYPE.WAV == soundType) {
long lengthMSEL = SoundUtil.getSoundLength(soundContentBytes, SoundUtil.SOUND_TYPE.WAV);
long frequency = SoundUtil.getSoundFrequency(soundContentBytes, SoundUtil.SOUND_TYPE.WAV);
long sampleCount = (lengthMSEL * frequency) / MILLISECOND;
if (4 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_UNCOMPRESSED, DefineSound.RATE_44000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (2 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_UNCOMPRESSED, DefineSound.RATE_22000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (1 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_UNCOMPRESSED, DefineSound.RATE_11000_HZ,
true, false, sampleCount, soundContentBytes);
} else if (0 == frequency / 10000) {
defineSound = new DefineSound(sound_id, DefineSound.FORMAT_UNCOMPRESSED, DefineSound.RATE_5500_HZ,
true, false, sampleCount, soundContentBytes);
} else {
return -1;
}
}
document.addTag(defineSound);
return sound_id;
}
/**
* start play sound
* @param document in falsh obj
* @param soundId in sound ID
*/
public void addStartSoundTag(SWFDocument document/*in*/, int soundId/*in*/) {
StartSound startSound = new StartSound(soundId, new SoundInfo());
document.addTag(startSound);
}
/**
* stop sound
* @param document in falsh ojb
* @param soundId in sound ID
*/
public void addStopSoundTag(SWFDocument document/*in*/, int soundId/*in*/) {
SoundInfo soundInfo = new SoundInfo();
soundInfo.setSyncStop();
StartSound startSound = new StartSound(soundId, soundInfo);
document.addTag(startSound);
}
/**
* add text
* @param document in falsh obj
* @param textContent in content
* @param family in type
* @param color in color
* @param size in size
*/
public int addTextTag(SWFDocument document/*in*/, String textContent/*in*/,
String family/*in*/, Color color/*in*/, int size/*in*/) {
int fontId = document.getNewCharacterId();
DefineFont2 defineFont2 = new DefineFont2(fontId, family, null, null);
document.addTag(defineFont2);
int textId = document.getNewCharacterId();
DefineEditText defineEditText = new DefineEditText(textId, new Rect(0, 0, 0, 0), null);
defineEditText.setAutoSize(true);
defineEditText.setFont(fontId, size);
defineEditText.setTextColor(
new RGBA(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
defineEditText.setReadOnly(true);
defineEditText.setInitialText(textContent);
document.addTag(defineEditText);
return textId;
}
/**
* add png file
* @param document in falsh obj
* @param picContentBytes in png content
*/
public int addPngTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/) {
try {
BufferedImage image = ImageUtilities.loadImage(
new ByteArrayInputStream(picContentBytes));
return addPngTag(document/*in*/, picContentBytes/*in*/,
image.getWidth()/*in*/, image.getHeight()/*in*/);
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
public int addPngTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/,
int imageWidth/*in*/, int imageHeight/*in*/) {
try {
byte[] picNewContentBytes = ImageUtil.zoom(picContentBytes/*in*/,
imageWidth/*in*/, imageHeight/*in*/);
BufferedImage image = ImageUtilities.loadImage(
new ByteArrayInputStream(picNewContentBytes));
RGBA bitmapAlpha[] = ImageUtilities.getRGBAArray(image);
AlphaBitmapData alphaMapData = new AlphaBitmapData(bitmapAlpha);
DefineBitsLossless2 bitsLossless2 = new DefineBitsLossless2(
document.getNewCharacterId(), DefineBitsLossless2.FORMAT_32_BIT_RGBA,
imageWidth, imageHeight, alphaMapData);
int img_id = bitsLossless2.getCharacterId();
document.addTag(bitsLossless2);
// ??*20???JSwiff?????twips????1/20px
Rect shapeBounds = new Rect(0, imageWidth*20, 0, imageHeight*20);
ShapeWithStyle styles = createShapeWithStyle(image, shapeBounds, img_id);
int shape_id = document.getNewCharacterId();
DefinitionTag shape = new DefineShape(shape_id, shapeBounds, styles);
document.addTag(shape);
return shape_id;
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
/**
* add gif
* @param document in falsh obj
* @param picContentBytes in gif content
*/
public int addGifSpriteTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/) {
int gifWidth = ImageUtil.getGifWidth(picContentBytes);
int gifHeight = ImageUtil.getGifHeight(picContentBytes);
return addGifSpriteTag(document/*in*/, picContentBytes/*in*/,
gifWidth/*in*/, gifHeight/*in*/);
}
public int addGifSpriteTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/,
int imageWidth/*in*/, int imageHeight/*in*/) {
int rtn = addGifTag(document/*in*/, picContentBytes/*in*/,
imageWidth/*in*/, imageHeight/*in*/);
if (-1 == rtn) {
return -1;
}
int defineSprite_id = document.getNewCharacterId();
DefineSprite defineSprite = new DefineSprite(defineSprite_id);
document.addTag(defineSprite);
for (int i = 0; i < gifCharacterIdVector.size(); i++) {
PlaceObject2 placeObject2 = new PlaceObject2(1);
placeObject2.setCharacterId(gifCharacterIdVector.get(i));
defineSprite.addControlTag(placeObject2);
int framePlays = gifFramePlayTimesVector.get(i);
for (int j = 0; j < framePlays; j++) {
defineSprite.addControlTag(new ShowFrame());
}
defineSprite.addControlTag(new RemoveObject2(1));
}
gifCharacterIdVector.clear();
gifFramePlayTimesVector.clear();
return defineSprite_id;
}
/**
* play gif
* @param document in falsh obj
* @param characterId in gif ID
* @param depth in gif depth
* @param x in
* @param y in
*/
public void addDisplayGifSpriteTag(SWFDocument document/*in*/, int characterId/*in*/,
int depth/*in*/, int x/*in*/, int y/*in*/) {
PlaceObject2 placeObject2New = new PlaceObject2(depth);
placeObject2New.setCharacterId(characterId);
placeObject2New.setMatrix(new Matrix(x, y));
document.addTag(placeObject2New);
}
/**
* disable gif
* @param document in falsh obj
* @param depth in gif depth
*/
public void addRemoveGifSpriteTag(SWFDocument document/*in*/, int depth/*in*/) {
document.addTag(new RemoveObject2(depth));
}
/**
* add jpeg
* @param document in falsh obj
* @param picContentBytes in jpg content
*/
public int addJpegTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/) {
try {
BufferedImage image = ImageUtilities.loadImage(
new ByteArrayInputStream(picContentBytes));
return addJpegTag(document/*in*/, picContentBytes/*in*/,
image.getWidth()/*in*/, image.getHeight()/*in*/);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public int addJpegTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/,
int imageWidth/*in*/, int imageHeight/*in*/) {
try {
byte[] picNewContentBytes = ImageUtil.zoom(picContentBytes/*in*/,
imageWidth/*in*/, imageHeight/*in*/);
BufferedImage image = ImageUtilities.loadImage(
new ByteArrayInputStream(picNewContentBytes));
byte imgByte[] = createImageByteArray(image, jpegQuality);
DefineBitsJPEG2 bitsJPEG2 = new DefineBitsJPEG2(document.getNewCharacterId(), imgByte);
int img_id = bitsJPEG2.getCharacterId();
document.addTag(bitsJPEG2);
// ??*20???JSwiff?????twips????1/20px
Rect shapeBounds = new Rect(0, imageWidth*20, 0, imageHeight*20);
ShapeWithStyle styles = createShapeWithStyle(image, shapeBounds, img_id);
int shape_id = document.getNewCharacterId();
DefinitionTag shape = new DefineShape(shape_id, shapeBounds, styles);
document.addTag(shape);
return shape_id;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public boolean setJpegQuality(int quality) {
if (1 < quality && 100 > quality) {
jpegQuality = quality;
return true;
}
return false;
}
public int getJpegQuality() {
return jpegQuality;
}
public int getPlayRate() {
return playRate;
}
public boolean setPlayRate(int newPlayRate/*in*/) {
if (0 > newPlayRate) {
return false;
}
playRate = newPlayRate;
return true;
}
private int addGifTag(SWFDocument document/*in*/, byte[] picContentBytes/*in*/,
int imageWidth/*in*/, int imageHeight/*in*/) {
try {
GifDecoder gifDecoder = new GifDecoder();
gifDecoder.read(new ByteArrayInputStream(picContentBytes));
int frameCount = gifDecoder.getFrameCount();
for (int i = 0; i < frameCount; i++) {
BufferedImage frame = gifDecoder.getFrame(i);
int framePlays = convertTimeToFrames(gifDecoder.getDelay(i));
gifFramePlayTimesVector.add(framePlays);
ByteArrayOutputStream out = new ByteArrayOutputStream();
javax.imageio.ImageIO.write(frame, "png", out);
int gifCharacterId = addPngTag(document/*in*/, out.toByteArray()/*in*/,
imageWidth/*in*/, imageHeight/*in*/);
gifCharacterIdVector.add(gifCharacterId);
}
return 0;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
private byte[] createImageByteArray(BufferedImage image/*in*/, int quality/*in*/) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
if (quality >= 0) {
ImageUtilities.saveImageAsJPEG(image, baos, quality);
} else {
ImageUtilities.saveImageAsJPEG(image, baos);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] imageData = baos.toByteArray();
int imageDataLength = imageData.length;
int headerLength = JPEG_DATA_HEADER.length;
byte[] extendedImageData = new byte[headerLength + imageDataLength];
System.arraycopy(JPEG_DATA_HEADER, 0, extendedImageData, 0, headerLength);
System.arraycopy(imageData, 0, extendedImageData, headerLength, imageDataLength);
return extendedImageData;
}
private ShapeWithStyle createShapeWithStyle(BufferedImage image/*in*/,
Rect shapeBounds/*in*/, int imageCharacterId/*in*/) {
Matrix bitmapMatrix = new Matrix(0, 0);
int shapeXMax = (int)shapeBounds.getXMax();
int shapeYMax = (int)shapeBounds.getYMax();
bitmapMatrix.setScale(shapeXMax/(image.getWidth()), shapeYMax/(image.getHeight()));
FillStyle fillStyle = new FillStyle(
imageCharacterId, bitmapMatrix, FillStyle.TYPE_NONSMOOTHED_CLIPPED_BITMAP);
FillStyleArray fillStyles = new FillStyleArray();
fillStyles.addStyle(fillStyle);
ShapeRecord[] shapeRecords = new ShapeRecord[5];
StyleChangeRecord styleChangeRecord = new StyleChangeRecord();
styleChangeRecord.setFillStyle1(1);
styleChangeRecord.setMoveTo(shapeXMax, shapeYMax);
shapeRecords[0] = styleChangeRecord;
shapeRecords[1] = new StraightEdgeRecord(-shapeXMax, 0);
shapeRecords[2] = new StraightEdgeRecord(0, -shapeYMax);
shapeRecords[3] = new StraightEdgeRecord(shapeXMax, 0);
shapeRecords[4] = new StraightEdgeRecord(0, shapeYMax);
ShapeWithStyle shapeWithStyle = new ShapeWithStyle(
fillStyles, new LineStyleArray(), shapeRecords);
return shapeWithStyle;
}
public static enum SOUND_TYPE{MP3, WAV};
private Vector<Integer> gifCharacterIdVector = new Vector<Integer>();
private Vector<Integer> gifFramePlayTimesVector = new Vector<Integer>();
private int jpegQuality = 50;
private int playRate = 12;
private static final int MILLISECOND = 1000;
private static final byte[] JPEG_DATA_HEADER = new byte[] {(byte)0xff,(byte)0xd9, (byte)0xff, (byte)0xd8};
}
|