SWT和AWT图像的互相转换 icon(AWT)--image(SWT)

 

最近做的RCP项目中,基本用的都是SWT,要在导出的RCP产品中运行起来时看到图片,只要使用

AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, imagePath);即可。

 

棘手的是,有部分图片,使用的是icon,因为对象GraphConstants只有setIcon( );这个方法来设置图像。

 所以我的思路就是,先使用AbstractUIPlugin.imageDescriptorFromPlugin( );

创建Image后再转换为icon使用。

 

一开始在网上只找到了“把Swing的Icon转换到SWT的Image”,和我要用的刚好相反,就在要放弃的时候,终于找到了以下这个特别强悍的代码,很好用。

时间比较紧迫,只是把代码拿来用了,具体的还没仔细学习研究,先整理记录一下。

******************************************************************************************************************************

SWT和AWT图像的互相转换

package convertimg;

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/**
 * 此类实现了SWT和AWT图像的互相转换
 * @author Administrator
 *
 */
public class Convertor {
 /**
  * SWT转换成AWT
  * @param org
  *            .eclipse.swt.graphics.ImageData;
  * @return java.awt.image.BufferedImage;
  */
 public static BufferedImage convertToAWT(ImageData data) {
  ColorModel colorModel = null;
  PaletteData palette = data.palette;
  if (palette.isDirect) {
   colorModel = new DirectColorModel(data.depth, palette.redMask,
     palette.greenMask, palette.blueMask);
   BufferedImage bufferedImage = new BufferedImage(colorModel,
     colorModel.createCompatibleWritableRaster(data.width,
       data.height), false, null);
   WritableRaster raster = bufferedImage.getRaster();
   int[] pixelArray = new int[3];
   for (int y = 0; y < data.height; y++) {
    for (int x = 0; x < data.width; x++) {
     int pixel = data.getPixel(x, y);
     RGB rgb = palette.getRGB(pixel);
     pixelArray[0] = rgb.red;
     pixelArray[1] = rgb.green;
     pixelArray[2] = rgb.blue;
     raster.setPixels(x, y, 1, 1, pixelArray);
    }
   }
   return bufferedImage;
  } else {
   RGB[] rgbs = palette.getRGBs();
   byte[] red = new byte[rgbs.length];
   byte[] green = new byte[rgbs.length];
   byte[] blue = new byte[rgbs.length];
   for (int i = 0; i < rgbs.length; i++) {
    RGB rgb = rgbs[i];
    red[i] = (byte) rgb.red;
    green[i] = (byte) rgb.green;
    blue[i] = (byte) rgb.blue;
   }
   if (data.transparentPixel != -1) {
    colorModel = new IndexColorModel(data.depth, rgbs.length, red,
      green, blue, data.transparentPixel);
   } else {
    colorModel = new IndexColorModel(data.depth, rgbs.length, red,
      green, blue);
   }
   BufferedImage bufferedImage = new BufferedImage(colorModel,
     colorModel.createCompatibleWritableRaster(data.width,
       data.height), false, null);
   WritableRaster raster = bufferedImage.getRaster();
   int[] pixelArray = new int[1];
   for (int y = 0; y < data.height; y++) {
    for (int x = 0; x < data.width; x++) {
     int pixel = data.getPixel(x, y);
     pixelArray[0] = pixel;
     raster.setPixel(x, y, pixelArray);
    }
   }
   return bufferedImage;
  }
 }

 /**
  * AWT转换成SWT
  * @param java
  *            .awt.image.BufferedImage;
  * @return org.eclipse.swt.graphics.ImageData;
  */
 public static ImageData convertToSWT(BufferedImage bufferedImage) {
  if (bufferedImage.getColorModel() instanceof DirectColorModel) {
   DirectColorModel colorModel = (DirectColorModel) bufferedImage
     .getColorModel();
   PaletteData palette = new PaletteData(colorModel.getRedMask(),
     colorModel.getGreenMask(), colorModel.getBlueMask());
   ImageData data = new ImageData(bufferedImage.getWidth(),
     bufferedImage.getHeight(), colorModel.getPixelSize(),
     palette);
   WritableRaster raster = bufferedImage.getRaster();
   int[] pixelArray = new int[3];
   for (int y = 0; y < data.height; y++) {
    for (int x = 0; x < data.width; x++) {
     raster.getPixel(x, y, pixelArray);
     int pixel = palette.getPixel(new RGB(pixelArray[0],
       pixelArray[1], pixelArray[2]));
     data.setPixel(x, y, pixel);
    }
   }
   return data;
  } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
   IndexColorModel colorModel = (IndexColorModel) bufferedImage
     .getColorModel();
   int size = colorModel.getMapSize();
   byte[] reds = new byte[size];
   byte[] greens = new byte[size];
   byte[] blues = new byte[size];
   colorModel.getReds(reds);
   colorModel.getGreens(greens);
   colorModel.getBlues(blues);
   RGB[] rgbs = new RGB[size];
   for (int i = 0; i < rgbs.length; i++) {
    rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF,
      blues[i] & 0xFF);
   }
   PaletteData palette = new PaletteData(rgbs);
   ImageData data = new ImageData(bufferedImage.getWidth(),
     bufferedImage.getHeight(), colorModel.getPixelSize(),
     palette);
   data.transparentPixel = colorModel.getTransparentPixel();
   WritableRaster raster = bufferedImage.getRaster();
   int[] pixelArray = new int[1];
   for (int y = 0; y < data.height; y++) {
    for (int x = 0; x < data.width; x++) {
     raster.getPixel(x, y, pixelArray);
     data.setPixel(x, y, pixelArray[0]);
    }
   }
   return data;
  }
  return null;
 }

 /**
  * 私有方法 只是为了测试 产生一个SWT的ImageData
  * @param display
  * @return
  */
 private static ImageData createSampleImage(Display display) {
  Image image = new Image(display, 100, 100);
  Rectangle bounds = image.getBounds();
  GC gc = new GC(image);
  gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
  gc.fillRectangle(bounds);
  gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
  gc.fillOval(0, 0, bounds.width, bounds.height);
  gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
  gc.drawLine(0, 0, bounds.width, bounds.height);
  gc.drawLine(bounds.width, 0, 0, bounds.height);
  gc.dispose();
  ImageData data = image.getImageData();
  image.dispose();
  return data;
 }
 /**
  * Main方法
  * @param args
  */
 public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display);
  shell.setText("SWT Image");
  ImageData data;
  if (args.length > 0) {
   String fileName = args[0];
   System.out.println(fileName);
   data = new ImageData(fileName);
  } else {
   //创建一个SWT的图像
   data = createSampleImage(display);
  }
  // 分别得到swt和awt图像
  final Image swtImage = new Image(display, data);
  final BufferedImage awtImage = convertToAWT(data);
  //下面是显示图像
  final Image swtImage2 = new Image(display, convertToSWT(awtImage));
  shell.addListener(SWT.Paint, new Listener() {
   public void handleEvent(Event e) {
    int y = 10;
    if (swtImage != null) {
     e.gc.drawImage(swtImage, 10, y);
     y += swtImage.getBounds().height + 10;
    }
    if (swtImage2 != null) {
     e.gc.drawImage(swtImage2, 10, y);
    }
   }
  });
  Frame frame = new Frame() {
   public void paint(Graphics g) {
    Insets insets = getInsets();
    if (awtImage != null) {
     g.drawImage(awtImage, 10 + insets.left, 10 + insets.top,
       null);
    }
   }
  };
  frame.setTitle("AWT Image");
  shell.setLocation(50, 50);
  Rectangle bounds = swtImage.getBounds();
  shell.setSize(bounds.width + 50, bounds.height * 2 + 100);
  Point size = shell.getSize();
  Point location = shell.getLocation();
  Insets insets = frame.getInsets();
  frame.setLocation(location.x + size.x + 10, location.y);
  frame.setSize(size.x - (insets.left + insets.right), size.y
    - (insets.top + insets.bottom));
  frame.setVisible(true);
  shell.open();
  while (!shell.isDisposed()) {
   if (!display.readAndDispatch())
    display.sleep();
  }
  if (swtImage != null)
   swtImage.dispose();
  if (swtImage2 != null)
   swtImage.dispose();
  frame.dispose();
  System.exit(0);
 }
}


转自http://www.java2s.com/CN/Code/Java/SWT-JFace-Eclipse/ConvertbetweenSWTImageandAWTBufferedImage.htm

******************************************************************************************************************************

Converts an AWT image to SWT

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;

import javax.swing.JPanel;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;

/**
* Utility class gathering some useful and general method.
* Mainly convert forth and back graphical stuff between
* awt and swt.
*/
public class SWTUtils {

    private final static String Az = "ABCpqr";

    /** A dummy JPanel used to provide font metrics. */
    protected static final JPanel DUMMY_PANEL = new JPanel();


    /**
     * Creates an AWT <code>MouseEvent</code> from a swt event.
     * This method helps passing SWT mouse event to awt components.
     * @param event The swt event.
     * @return A AWT mouse event based on the given SWT event.
     */
    public static MouseEvent toAwtMouseEvent(org.eclipse.swt.events.MouseEvent event) {
        int button = MouseEvent.NOBUTTON;
        switch (event.button) {
        case 1: button = MouseEvent.BUTTON1; break;
        case 2: button = MouseEvent.BUTTON2; break;
        case 3: button = MouseEvent.BUTTON3; break;
        }
        int modifiers = 0;
        if ((event.stateMask & SWT.CTRL) != 0) {
            modifiers |= InputEvent.CTRL_DOWN_MASK;
        }
        if ((event.stateMask & SWT.SHIFT) != 0) {
            modifiers |= InputEvent.SHIFT_DOWN_MASK;
        }
        if ((event.stateMask & SWT.ALT) != 0) {
            modifiers |= InputEvent.ALT_DOWN_MASK;
        }
        MouseEvent awtMouseEvent = new MouseEvent(DUMMY_PANEL, event.hashCode(),
                event.time, modifiers, event.x, event.y, 1, false, button);
        return awtMouseEvent;
    }

    /**
     * Converts an AWT image to SWT.
     *
     * @param image  the image (<code>null</code> not permitted).
     *
     * @return Image data.
     */
    public static ImageData convertAWTImageToSWT(Image image) {
        if (image == null) {
            throw new IllegalArgumentException("Null 'image' argument.");
        }
        int w = image.getWidth(null);
        int h = image.getHeight(null);
        if (w == -1 || h == -1) {
            return null;
        }
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return convertToSWT(bi);
    }

    /**
     * Converts a buffered image to SWT <code>ImageData</code>.
     *
     * @param bufferedImage  the buffered image (<code>null</code> not
     *         permitted).
     *
     * @return The image data.
     */
    public static ImageData convertToSWT(BufferedImage bufferedImage) {
        if (bufferedImage.getColorModel() instanceof DirectColorModel) {
            DirectColorModel colorModel
                    = (DirectColorModel) bufferedImage.getColorModel();
            PaletteData palette = new PaletteData(colorModel.getRedMask(),
                    colorModel.getGreenMask(), colorModel.getBlueMask());
            ImageData data = new ImageData(bufferedImage.getWidth(),
                    bufferedImage.getHeight(), colorModel.getPixelSize(),
                    palette);
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[3];
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    raster.getPixel(x, y, pixelArray);
                    int pixel = palette.getPixel(new RGB(pixelArray[0],
                            pixelArray[1], pixelArray[2]));
                    data.setPixel(x, y, pixel);
                }
            }
            return data;
        }
        else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
            IndexColorModel colorModel = (IndexColorModel)
                    bufferedImage.getColorModel();
            int size = colorModel.getMapSize();
            byte[] reds = new byte[size];
            byte[] greens = new byte[size];
            byte[] blues = new byte[size];
            colorModel.getReds(reds);
            colorModel.getGreens(greens);
            colorModel.getBlues(blues);
            RGB[] rgbs = new RGB[size];
            for (int i = 0; i < rgbs.length; i++) {
                rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF,
                        blues[i] & 0xFF);
            }
            PaletteData palette = new PaletteData(rgbs);
            ImageData data = new ImageData(bufferedImage.getWidth(),
                    bufferedImage.getHeight(), colorModel.getPixelSize(),
                    palette);
            data.transparentPixel = colorModel.getTransparentPixel();
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[1];
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    raster.getPixel(x, y, pixelArray);
                    data.setPixel(x, y, pixelArray[0]);
                }
            }
            return data;
        }
        return null;
    }

}

http://www.java2s.com/Tutorial/Java/0280__SWT/ConvertsanAWTimagetoSWT.htm

******************************************************************************************************************************

把Swing的Icon转换到SWT的Image

 

环境:Windows7、Eclipse 3.5、JRE1.6
最近在研究SWT的TreeView控件,想要写一个类似于Windows资源管理器的目录树,弄了半天,目录树是出来了,但是图标搞不出来,何解?FileSystemView.getFileSystemView().getSystemIcon(File f)这个函数返回的是个Icon对象,是用在Swing上的,而我的目录树采用的是SWT/JFace TreeViewer控件,其ILabelProvider的getImage()接口返回的是SWT的Image对象。这两个玩意儿得转换一下才能使用。
在网上找了半天的资料,发现没有现成的API可以一句话就完成转换,都是需要写一段代码来完成。有几个方案,基本思路都是将Icon对象内所包含的Icon数据转换成数据流,然后根据这个数据流重新生成Image,其代码如下:

@Override
public Image getImage(Object element)
{
    //得到文件图标
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);
    java.awt.Image image = systemIcon.getImage();
 
    int width = image.getWidth(null);
    int height = image.getHeight(null);
    //创建用于绘制Icon的缓冲区
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 
    //绘制Icon到缓冲区
    Graphics2D g2d = bufferedImage.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    //读取缓冲区图片数据到一个数组
    int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();
    //根据数组数据生成ImageData对象
    ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
    imageData.setPixels(0, 0, data.length, data, 0);
    //生成Image对象
    Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(), imageData);
    return swtImage;
}

Icon的确是转换到Image了,看下面的效果图:
虽然Icon转换到了Image,可是图片周围全都是黑色,这是因为Icon在转换的时候,原来的图片里面是透明色的像素点,转换过来系统自动变成了黑色,因此代码还需要额外的处理一下,修改后的代码如下:

@Override
public Image getImage(Object element)
{
    //得到文件图标
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);
    java.awt.Image image = systemIcon.getImage();
 
    int width = image.getWidth(null);
    int height = image.getHeight(null);
    //创建用于绘制Icon的缓冲区
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 
    //绘制Icon到缓冲区
    Graphics2D g2d = bufferedImage.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    //读取缓冲区图片数据到一个数组
    int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();
    //将没有颜色的点设置为白色
    for (int i = 0; i &lt; data.length; i++)
    {
    if (data[i] == 0)
         data[i] = 0xFFFFFF;
    }
    //根据数组数据生成ImageData对象
    ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
    imageData.setPixels(0, 0, data.length, data, 0);
    //生成Image对象
    Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(), imageData);
    return swtImage;
}

和上面的代码相比,新增加了一个循环,将缓冲区内为0的数据修改为0xFFFFFF,也就是将相应的像素设置为白色,效果图如下:
看起来效果好多了,可是如果目光敏锐一点的话,还是能够看出破绽来,截取一个图标,放大后仔细看一看:
和正常的图标对比一下,可以发现边边角角的颜色都不对,普遍偏深,可是网上找到的资料到这里就为止了,没有人提出来如何解决这个问题,当然,这也可能跟我的系统有关系。经过跟踪和调试,发现其实调用systemIcon.getImage() 得到的对象就已经是一个BufferedImage对象了,没有必要再去重新new一个,而事实证明,就是这个new操作,导致转换后的图片出现上述问题。
根据systemIcon.getImage()得到BufferedImage对象后,因为该对象内部数据实际上就已经是文件图标数据了,所以调用Graphics2D绘制Icon的操作也没必要了,最后修改后的代码如下:

@Override
public Image getImage(Object element)
{
    //得到文件图标
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);
    java.awt.Image image = systemIcon.getImage();
 
    int width = image.getWidth(null);
    int height = image.getHeight(null);
    //得到Icon的数据缓冲区
    BufferedImage bufferedImage = (BufferedImage) systemIcon.getImage();
    //读取缓冲区图片数据到一个数组
    int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();
    //将没有颜色的点设置为白色
    for (int i = 0; i &lt; data.length; i++)
    {
    if (data[i] == 0)
        data[i] = 0xFFFFFF;
    }
    //根据数组数据生成ImageData对象
    ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
    imageData.setPixels(0, 0, data.length, data, 0);
    //生成Image对象
    Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(), imageData);
    return swtImage;
}

这回效果图如下:
看起来好看多了,基本上跟Windows资源管理器的效果差不多了。不过如果目光依旧敏锐的话,再继续打开某一驱动器,看文件夹图标,还是有一点小小的瑕疵,有些Icon在转换过来的时候,会莫名其妙的在原来没有颜色的像素点上增加一点淡淡的颜色,不过影响已经不大了,就姑且这样吧。期待有高手能够进一步将其搞定。
好消息,这个问题我自己搞定了,参见
《把Swing的Icon转换到SWT的Image(续)》这篇文档。

本文出自 “rainman” 博客,请务必保留此出处http://lancelot.blog.51cto.com/393579/331636

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值