SWT显示GIF动态图片工具类

整理了一个工具类, 用于在SWT中显示GIF图片


/**
* 用于显示GIF图片的util类
*
* @author mark.wang
*/
public class ImageViewer extends Canvas {

protected Point origin = new Point(0, 0);
protected Image image;
protected ImageData[] imageDatas;
protected Image[] images;
protected int current;

private int repeatCount;
private Runnable animationTimer;
private Color bg;
private Display display;

public ImageViewer(Composite parent) {
super(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE);

bg = getBackground();
display = getDisplay();
addListeners();
}

/**
* @param repeatCount
* 0 forever
*/
public void setImages(ImageData[] imageDatas, int repeatCount) {
checkWidget();

this.image = null;
this.imageDatas = imageDatas;
this.repeatCount = repeatCount;
convertImageDatasToImages();
startAnimationTimer();
redraw();
}

@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
checkWidget();

Image image = getCurrentImage();
if (image != null) {
Rectangle rect = image.getBounds();
Rectangle trim = computeTrim(0, 0, rect.width, rect.height);
return new Point(trim.width, trim.height);
}

return new Point(wHint, hHint);
}

@Override
public void dispose() {
if (image != null)
image.dispose();

if (images != null)
for (int i = 0; i < images.length; i++)
images[i].dispose();

super.dispose();
}

protected void paint(Event e) {
Image image = getCurrentImage();
if (image == null)
return;

GC gc = e.gc;
gc.drawImage(image, origin.x, origin.y);

gc.setBackground(bg);
Rectangle rect = image.getBounds();
Rectangle client = getClientArea();
int marginWidth = client.width - rect.width;
if (marginWidth > 0) {
gc.fillRectangle(rect.width, 0, marginWidth, client.height);
}
int marginHeight = client.height - rect.height;
if (marginHeight > 0) {
gc.fillRectangle(0, rect.height, client.width, marginHeight);
}
}

void addListeners() {
addListener(SWT.Paint, new Listener() {
public void handleEvent(Event e) {
paint(e);
}
});
}


void convertImageDatasToImages() {
images = new Image[imageDatas.length];

// Step 1: Determine the size of the resulting images.
int width = imageDatas[0].width;
int height = imageDatas[0].height;

// Step 2: Construct each image.
int transition = SWT.DM_FILL_BACKGROUND;
for (int i = 0; i < imageDatas.length; i++) {
ImageData id = imageDatas[i];
images[i] = new Image(display, width, height);
GC gc = new GC(images[i]);

// Do the transition from the previous image.
switch (transition) {
case SWT.DM_FILL_NONE:
case SWT.DM_UNSPECIFIED:
// Start from last image.
gc.drawImage(images[i - 1], 0, 0);
break;
case SWT.DM_FILL_PREVIOUS:
// Start from second last image.
gc.drawImage(images[i - 2], 0, 0);
break;
default:
// DM_FILL_BACKGROUND or anything else,
// just fill with default background.
gc.setBackground(bg);
gc.fillRectangle(0, 0, width, height);
break;
}

// Draw the current image and clean up.
Image img = new Image(display, id);
gc.drawImage(img, 0, 0, id.width, id.height, id.x, id.y, id.width,
id.height);
img.dispose();
gc.dispose();

// Compute the next transition.
// Special case: Can't do DM_FILL_PREVIOUS on the
// second image since there is no "second last"
// image to use.
transition = id.disposalMethod;
if (i == 0 && transition == SWT.DM_FILL_PREVIOUS)
transition = SWT.DM_FILL_NONE;
}
}

Image getCurrentImage() {
if (image != null)
return image;

if (images == null)
return null;

return images[current];
}

void startAnimationTimer() {
if (images == null || images.length < 2)
return;

final int delay = imageDatas[current].delayTime * 10;
display.timerExec(delay, animationTimer = new Runnable() {
public void run() {
if (isDisposed())
return;

current = (current + 1) % images.length;
redraw();

if (current + 1 == images.length && repeatCount != 0
&& --repeatCount <= 0)
return;
display.timerExec(delay, this);
}
});
}

void stopAnimationTimer() {
if (animationTimer != null)
display.timerExec(-1, animationTimer);
}

public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
CopyOfImageViewer ic = new CopyOfImageViewer(shell);

shell.setLayout(new FillLayout());
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setText(" Open an gif image file or cancel, only gif ");
String string = dialog.open();

ImageLoader loader = new ImageLoader();
ImageData[] imageDatas = loader.load(string);
ic.setImages(imageDatas, loader.repeatCount);

ic.pack();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值