/**
*
*/
package com.javaxyq.tools;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Logger;
import com.javaxyq.util.Utils;
import com.javaxyq.widget.Animation;
import com.javaxyq.widget.Frame;
import com.javaxyq.widget.Sprite;
/**
* ������ȡ��
* @author gongdewei
* @date 2011-8-13 create
*/
public class SpriteExtractor implements Extractor {
private static final Logger log = Logger.getLogger(SpriteExtractor.class.getName());
@Override
public void extract(FileObject fileObject, File dir, Map<String, ?> options) {
String type = fileObject.getContentType();
if (!FileObject.TCP_FILE.equals(type)) {
log.warning("����������ֹ���ļ����Ͳ��ǣ�"+FileObject.TCP_FILE);
return;
}
if(!dir.exists()) {
dir.mkdirs();
}
log.info("�������飺"+fileObject.getPath()+" ...");
//�ж��Ƿ�����ͼƬ
boolean isTrim = "true".equalsIgnoreCase((String) options.get("trim_image"));
Sprite sprite = XYQTools.createSprite(fileObject);
int animCount = sprite.getAnimationCount();
int frameCount = sprite.getAnimation(0).getFrameCount();
SpriteDescriptor descriptor = new SpriteDescriptorImpl(animCount, frameCount);
for (int animIndex = 0; animIndex < animCount; animIndex++) {
Animation anim = sprite.getAnimation(animIndex);
Vector<Frame> frames = anim.getFrames();
for (int frameIndex = 0; frameIndex < frames.size(); frameIndex++) {
Frame frame = frames.get(frameIndex);
descriptor.setFrameWidth(animIndex,frameIndex, anim.getWidth());
descriptor.setFrameHeight(animIndex,frameIndex, anim.getHeight());
descriptor.setFrameRefPixel(animIndex,frameIndex, frame.getRefPixelX(), frame.getRefPixelY());
saveImage(frame, animIndex, frameIndex, dir, descriptor, isTrim);
log.fine("�ѵ���֡��"+animIndex+"-"+frameIndex);
}
log.info("�ѵ���������"+animIndex);
}
//���澫������
saveDescriptor(dir, descriptor);
log.info("�ɹ��������鵽Ŀ¼��"+dir.getAbsolutePath());
}
private void saveDescriptor(File dir, SpriteDescriptor descriptor) {
try {
String encodeDescriptor = descriptor.encode();
File file = new File(dir, "des.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(encodeDescriptor.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveImage(Frame frame, int animIndex, int frameIndex, File dir, SpriteDescriptor descriptor, boolean isTrim) {
//BufferedImage tmpImage = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_ARGB);
//Graphics2D g2d = tmpImage.createGraphics();
//g2d.setComposite(AlphaComposite.SrcOver);
//g2d.drawImage(frame.getImage(), 0, 0, null);
String filename = animIndex+"-"+frameIndex+".png";
BufferedImage image = (BufferedImage) frame.getImage();
if(isTrim) {
image = trimImage(image, descriptor, animIndex, frameIndex);
}
Utils.writeImage(image, new File(dir, filename), "png");
//tmpImage.flush();
//g2d.dispose();
}
private BufferedImage trimImage(BufferedImage source, SpriteDescriptor descriptor, int animIndex, int frameIndex) {
int minX = 0, minY = 0;
int maxX = source.getWidth()-1;
int maxY = source.getHeight()-1;
while( minX < maxX && isTransparentX(source, minX)) {
minX ++;
}
while( maxX > minX && isTransparentX(source, maxX)) {
maxX --;
}
while( minY < maxY && isTransparentY(source, minY)) {
minY ++;
}
while( maxY > minY && isTransparentY(source, maxY)) {
maxY --;
}
if(minX!=0 || minY!=0 || maxX!=source.getWidth()-1 || maxY!=source.getHeight()-1) {
log.fine("trim image to: ("+minX+","+minY+","+maxX+","+maxY+")");
Point refPixel = descriptor.getFrameRefPixel(animIndex, frameIndex);
refPixel.x -= minX;
refPixel.y -= minY;
descriptor.setFrameRefPixel(animIndex, frameIndex, refPixel.x, refPixel.y);
descriptor.setFrameWidth(animIndex, frameIndex, maxX-minX);
descriptor.setFrameHeight(animIndex, frameIndex, maxY-minY);
}
return source.getSubimage(minX, minY, maxX-minX, maxY-minY);
}
private boolean isTransparentX(BufferedImage source, int x) {
int h = source.getHeight();
for (int i = 0; i < h; i++) {
if(source.getRGB(x, i)!=0) {
return false;
}
}
return true;
}
private boolean isTransparentY(BufferedImage source, int y) {
int w = source.getWidth();
for (int i = 0; i < w; i++) {
if(source.getRGB(i,y)!=0) {
return false;
}
}
return true;
}
}