- 浏览: 88704 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
chenlog:
thank you so much~~~
java中图像简单处理 -
dang_java:
Thanks.
java中图像简单处理 -
wangxinpier:
adobe reader有一个繁体字体需要安装一下
birt 3.7.1导出PDF报表中文问题
Java简单图像处理
Java图像格式转换
ImageIO 目前支持一下格式: BMP, JPG,PNG, JPEG, WBMP, GIF
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageIOTest {
public static void main(String args[]) throws IOException {
File inputFile = new File("c:\\11.jpg");
BufferedImage input = ImageIO.read(inputFile);
ImageIO.write(input, "GIF", outputFile);
//ImageIO.write(input, "JPEG", outputFile);
//ImageIO.write(input, "JPG", outputFile);
//ImageIO.write(input, "PNG", outputFile);
}
}
还可以使用JAI(sun公司java advanced imaging,三个重要的jar文件mlibwrapper_jar.jar、jar_codec.jar和jar_core.jar移到你的classpath环境变量指定的目录下。我们推荐把它们放到你的JDK的jre/lib/ext目录下。)jimi(sun公司)。
SWT图像介绍
这部分内容大多是以前从网上找的,出处不记得了,望原版见谅。
SWT Images简介
软件开发人员可以利用 SWT 封装的 Image, ImageData 等类来创建图像、存储图像数据,也可以对存储的图像数据进行各种图像变换。本文将演示如何正确的使用 Image, ImageData 等类,以及如何使图像变灰、变亮/黑、图像旋转、图像拉伸、图片透明叠加、图片反色等相关问题。
下面就来介绍一下 Image 和 ImageData 这两个在 SWT Images 中最重要的类。
类 org.eclipse.swt.graphics.Image 被用来表示可以在设备上显示的图片,可以用方法如GC.drawImage() 或者 Button.setImage() 等来将它显示出来。Image 类提供了几个构造函数,可以完成以下功能:
• 装载一个现有的图象。可以通过传入文件名或者 InputStream 作为参数,但是图象的格式必须是它所支持的格式之(目前 SWT Image 支持 BMP、GIF、JPG、PNG、Windows ICO 等格式)一,否则会抛出 SWTException 异常。
• 构造一个用已经存在的 ImageData 进行初始化的图像。
• 构造一个空图像。可以通过修改其像素值或者向它拷贝一个 SWT 图形上下文的内容 (GC) 来绘制该图像,并且可以指定空图像的大小。
类 org.eclipse.swt.graphics.ImageData 中存储了图像的像素数据信息。 ImageData 是一个包含有关图像大小、调色板、颜色值和透明度等信息的类。我们可以对这些图像像素数据可以直接读或者写操作,这意味着可以通过直接读取或者修改图像的数据,来设置或者取得图像中任何像素或者任何一组像素的颜色值。关于 ImageData ,我们还应当了解以下一些字段:
• width 和 height 指定图像的宽和高。Depth 指定图像的颜色深度。可能的值为 1、2、4、8、16、24 或者 32,指定编码每一个像素的值所使用的比特数。
• alpha 与 alphaData 定义图像的透明度。alpha 定义了图象的全局透明度值,默认值为 -1,并且alphaData 域将被忽略。当 alpha 不等于 -1 时, alphaData 存储了图象的透明度缓冲区,每个像素可以有一个在 0~255 之间的透明度值,数值越大,表示越不透明。值得注意的是,只有部分图象格式具有透明度,例如 GIF 和 PNG。
• palette 包含一个 PaletteData 对象,它存储有关图像的颜色模型的信息。SWT 的颜色模型可以是索引或者直接的,由palette的域 isDirect 来指定。如果颜色模型是索引的,那么 PaletteData 包含颜色索引,可以通过方法 getRGBs() 来获取 RGB 信息。如果它是直接的,那么它包含转换信息,表明应当如何从像素的整数值中提取出颜色 RGB 成分。
• data 包含像素值的字节缓冲区。字节编码的方法取决于所使用的颜色深度。对于一个 8 位的图像,数组中的一个字节正好表示图像中一个像素的值。对于 16 位图像,每一个像素值编码为缓冲区中的两个字节。这两个字节以最低有效字节顺序存储。对于 24 或者 32 位图像,每一个像素值以最高有效位字节顺序编码为缓冲区中的三个或者四个字节。
• bytesPerLine 表明缓冲区中有多少字节用于表示图像中一行像素的所有像素值。由于一个像素可能有多个字节表示,所以 bytesPerLine 可能是字段 width 值的若干倍。也就是说“一个像素扫描行上有多少个字节”,我们知道表示一个像素可能需要1,、3、4…n个字节等(分别对应256灰度图,24位真彩色等),因此,通过bytesPerPixel = bytesPerLine÷n就可以知道,一个扫描行上有多少个像素。我们将bytesPerPixel称为每个像素所占的字节数。
________________________________________
SWT图象处理
常见的图象处理包含图象的读/写、图像变灰、变亮/黑、图像旋转、图像拉伸、图片透明叠加、图片反色等。下面将就这些问题逐个介绍,表 1 列出了各个清单所对应的图像处理。
图像的读写
我们可以使用类 org.eclipse.swt.graphics.ImageLoader 来加载或者保存图像。 ImageLoader 具有一个全局的成员变量 ImageData[],它用于存储图片数据。
清单 1. 图像读写示例
图像可以直接得到
Image image = new Image(display, “e:/aa.jpg”);
我们还可以用ImageLoader得到(不仅能得到,还能保存为各种格式的图像文件,)
ImageLoader loader = new ImageLoader();
ImageData[] imgD = loader.load("icons/ipod.jpg");
if(imgD!=null&&imgD.length>0)
{
image = new Image(display, imgD[0]);
label.setImage(image);
loader.data[0] = image.getImageData();
loader.save("icons/qqq.png", SWT.IMAGE_PNG);
}
图像变灰
图像变灰在桌面应用程序中有着广泛的应用。例如,一个图标被作为一个按钮的背景,我们需要一个灰色效果的图标作为按钮的背景来表示这个按钮处于禁用状态。在SWT中,基于已经存在的图像来创建一个具有灰色效果的图像,我们可以使用构造函数 Image(Display display, Image image, int flag) 来创建,其中参数 flag 使用 SWT.IMAGE_GRAY。
清单 2. 图像变灰示例
Image newImage = new Image(null, image, SWT.IMAGE_GRAY);
图像变亮/变黑
下面讨论图像变亮/变黑。 RGB 和 HSL (也叫 HSB/HSV )是两种色彩空间,即:红、绿、蓝( Red, Green, Blue) 和色调、饱和度、亮度( Hue, Saturation, Lightness 或 Brightness 或 Value),前者适用于机器采样,目前的显示器颜色即由这三种基色构成,而后者更符合人类的直观感觉。在 Windows 的标准颜色对话框中均包含这两种表示方法。 RGB 的取值范围在 0~255 之间, HSL 的取值在 0~1 之间。因此我们只需要将 HSL 空间数据的 L 分量进行调整即可调整此图像的亮度。要实现图像变亮/变黑的功能,只需要调整清单 3 中函数 lightImage 行(*)中等号右边的值( 0 到 1 之间)。
清单 3. 图像变亮示例
private static ImageData lightImage(ImageData srcData) {
double[] data = rgbTohsl(srcData.data);
byte[] newData = new byte[srcData.data.length];
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.width * bytesPerPixel;
for(int i = 0; i < data.length; i += 3) {
data[i + 2] = 0.75; //----------------- (*)
}
data = hslTorgb(data);
for(int i = 0; i < srcData.data.length; i ++) {
newData[i] = (byte)data[i];
}
ImageData newImageData = new ImageData(srcData.width,
srcData.height,
srcData.depth,
srcData.palette,
destBytesPerLine,
newData);
return newImageData;
}
其中,方法 double[] rgbTohsl(byte[] data) 是把 RGB 空间数据转换到 HSL 空间;相反的,方法 double[] hslTorgb(double[] data) 是把数据从 HSL 空间转换到 RGB 空间。
图像旋转
清单4中方法 rotate 实现了将图像相左旋转 90 度。如图 1 ,对于像素点 (x, y) ,向左旋转90 度以后,它在图象中的位置变成了 (y, width - x - 1) 。因此,相左旋转 90 度即将所有的像素点按照规则换一下位置。其他的旋转可用同样的方法。
旋转中心点为图形左下角,旋转90度的计算公式:
X’ = y;
y’= -x;
旋转中心点为图形左上角,旋转90度的计算公式:
X’ = -y;
y’= x;
旋转中心点为图形中心点,坐标为计算机平面坐标(左上角为(0,0)),旋转90度的计算公式:
X’ = y;
y’= width-x-1;
旋转中心点为图形中心点,坐标为左下角为(0,0),旋转90度的计算公式:
X’ = height –y -1;
y’= x;
图1 旋转前与相左旋转 90 度后
清单4. 图像旋转示例
private static ImageData rotate(ImageData srcData) {
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.height * bytesPerPixel;
byte[] newData = new byte[srcData.data.length];
int width = 0, height = 0;
for (int srcY = 0; srcY < srcData.height; srcY++) {
for (int srcX = 0; srcX < srcData.width; srcX++) {
int destX = 0, destY = 0, destIndex = 0, srcIndex = 0;
destX = srcY;
destY = srcData.width - srcX - 1;
width = srcData.height;
height = srcData.width;
destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel);
srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel);
System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel);
}
}
return new ImageData(width, height, srcData.depth, srcData.palette, destBytesPerLine, newData);
}
图像反色
对于彩色图像的 R、G、B 各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理,其算法很简单,假设源图像一像素的红,绿,蓝分量为 (R,G,B),则目标图像该像素的红绿蓝分量应变为 (255 - R,255 - G, 255 - B)。
清单5. 图像反色示例
private static ImageData reverseImage(ImageData srcData)
{
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.width * bytesPerPixel;
byte[] newData = srcData.data;
for (int i = 0; i < newData.length; i++)
newData[i] = (byte)(255 - newData[i]);
ImageData newImageData = new ImageData(srcData.width, srcData.height, srcData.depth, srcData.palette, destBytesPerLine, newData);
newImageData.transparentPixel = srcData.transparentPixel;
return newImageData;
}
图像拉伸
图像的缩小/放大一般分为按比例缩小和不按比例缩小两种。图像的缩小操作中,是在现有的信息里如何挑选所需要的有用信息。图像的放大操作中,则需对尺寸放大后所多出来的空格填入适当的值,这是信息的估计问题,所以较图像的缩小要难一些,而且图像大比例放大时经常会出现马赛克效应。庆幸的是,SWT 工具箱对图像的拉伸进行了封装,开发者只需要调用方法 ImageData.scaledTo(int width, int height) 来获得一个拉伸后的 ImageData。
清单6. 图像拉伸示例
Image newImage = new Image(null, imageData[0].scaledTo(imageData[0].width / 2,imageData[0].height / 2));
图片透明叠加
透明叠加方式是图象处理中常用的一种处理方式,在这种处理方式中,一幅图片叠加到另一幅图片上,但是这幅图象不是完全将原来的图象覆盖,而是能够部分的透过叠加的图象显示出来,透明的程度由透明度参数指定(假定为 a,其值在 0 与 1 之间,数值越小表明被叠加的图片越透明),其原理是目标图片的 R、G、B 以及 alpha 分别为待叠加图片A的 R、G、B 以及 alpha 分量乘以透明度参数 a 加上待叠加图片B的 R、G、B 以及 alpha 分量乘以 1-a 的值。我们可以使用图片的透明叠加作出水印的效果。
清单7. 图像透明叠加示例
private static ImageData watermark(ImageData srcData1, ImageData srcData2, double alpha)
{
if (srcData1.width != srcData2.width || srcData1.height != srcData2.height || srcData1.bytesPerLine != srcData2.bytesPerLine)
// 未考虑不同大小图片的叠加
return null;
int bytesPerPixe = srcData1.bytesPerLine / srcData1.width;
int destBytesPerLine = srcData1.width * bytesPerPixe;
byte[] newData = new byte[srcData1.data.length];
ImageData newImageData = new ImageData(srcData1.width, srcData1.height, srcData1.depth, srcData1.palette, destBytesPerLine, newData);
for (int srcY = 0; srcY < srcData1.height; srcY++)
{
for (int srcX = 0; srcX < srcData1.bytesPerLine; srcX++)
{
int idx = srcY * srcData1.bytesPerLine + srcX;
newImageData.data[idx] = (byte)(alpha * srcData1.data[idx] + (1 - alpha) * srcData2.data[idx]);
}
}
return newImageData;
}24位真彩色图转为256色图(灰度图)
彩色图像转换为黑白图像时需要计算图像中每像素有效的亮度值,通过匹配像素亮度值可以轻松转换为黑白图像。
计算像素有效的亮度值可以使用下面的公式:
Y=0.3red+0.59green+0.11blue
然后使用 Color.FromArgb(Y,Y,Y) 来把计算后的值转换
转换代码可以使用下面的方法来实现:
按照以上同样的方法我们有:
public static Image convertToGrayscale(Image source )
{
if(source == null )return null;
ImageData ida = source.getImageData();
byte[] data2 = new byte[ida.data.length];
int offset = 0;
int k = 0;
int r, g,b,gray;
for(int i=0;i<ida.height;i++)
{
for(int j=0;j<ida.width;j++)
{
k = offset+j*3;
b = ida.data[k]&0xff;
g = ida.data[k + 1]&0xff;
r = ida.data[k + 2]&0xff;
gray = (int) (0.11*b + 0.59*g + 0.3*r);
data2[k]=data2[k+1]=data2[k+2]=(byte)gray;
}
offset += ida.bytesPerLine;
}
ImageData ida2 = new ImageData(ida.width, ida.height, ida.depth, ida.palette, ida.scanlinePad, data2);
Return new Image(source.getDevice(),ida2);
}
另外,我们也可以直接利用swt image在new 的时候指定flag来做到:
Image img1 = new Image(display,"E:/资料/小内容/Winter.jpg");
Image img2 = new Image(display,img1,SWT.IMAGE_GRAY);
Image的flag目前共有3个分别是SWT.IMAGE_GRAY, SWT.IMAGE_COPY, SWT.IMAGE_DISABLE。
经过与swt image中生成SWT.IMAGE_GRAY的计算方法。发现上面的清单有问题,具体再查。先这么着吧。
图像旋转/放大/移动的坐标对应
x = 1/ω * [x1*cos θ + y1*sinθ – (x0*cosθ + y0*sinθ)];
y = 1/ω * [y1*cosθ – x1*sinθ – (y0*cosθ - x0*sinθ)];
(x ,y)是原图中的点
(x1,y1)是视图窗口中的点
θ是旋转的角度
ω是放大倍数
(x0,y0)是平移时鼠标移动的偏移量
SWT_Image界面操作
图像拖动
public class DragImage
{
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.H_SCROLL | SWT.V_SCROLL);
final Composite composite = new Composite(shell, SWT.BORDER);
composite.setEnabled(false);
composite.setLayout(new FillLayout());
composite.setSize(700, 600);
final Color red = display.getSystemColor(SWT.COLOR_RED);
composite.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
e.gc.setBackground(red);
e.gc.fillOval(5, 5, 690, 590);
}
});
final ScrollBar hBar = shell.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
Point location = composite.getLocation();
location.x = -hBar.getSelection();
composite.setLocation(location);
}
});
final ScrollBar vBar = shell.getVerticalBar();
vBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
Point location = composite.getLocation();
location.y = -vBar.getSelection();
composite.setLocation(location);
}
});
shell.addListener(SWT.Resize, new Listener()
{
public void handleEvent(Event e)
{
Point size = composite.getSize();
Rectangle rect = shell.getClientArea();
hBar.setMaximum(size.x);
vBar.setMaximum(size.y);
hBar.setThumb(Math.min(size.x, rect.width));
vBar.setThumb(Math.min(size.y, rect.height));
int hPage = size.x - rect.width;
int vPage = size.y - rect.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
Point location = composite.getLocation();
if (hSelection >= hPage)
{
if (hPage <= 0)
hSelection = 0;
location.x = -hSelection;
}
if (vSelection >= vPage)
{
if (vPage <= 0)
vSelection = 0;
location.y = -vSelection;
}
composite.setLocation(location);
}
});
final Point[] offset = new Point[1];
Listener listener = new Listener()
{
public void handleEvent(Event event)
{
switch (event.type)
{
case SWT.MouseDown:
Rectangle rect = composite.getBounds();
if (rect.contains(event.x, event.y))
{
Point pt1 = composite.toDisplay(0, 0);
Point pt2 = shell.toDisplay(event.x, event.y);
offset[0] = new Point(pt2.x - pt1.x, pt2.y - pt1.y);
}
break;
case SWT.MouseMove:
if (offset[0] != null)
{
Point pt = offset[0];
composite.setLocation(event.x - pt.x, event.y - pt.y);
System.out.println("x : " + event.x + " y : " + event.y);
hBar.setSelection(pt.x - event.x);
vBar.setSelection(pt.y - event.y);
}
break;
case SWT.MouseUp:
offset[0] = null;
break;
}
}
};
shell.addListener(SWT.MouseDown, listener);
shell.addListener(SWT.MouseUp, listener);
shell.addListener(SWT.MouseMove, listener);
shell.setSize(600, 500);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
图像的几种显示
public class ImageProcesser
{
/*
* 图像按原始大小显示,当面板尺寸小于图像尺寸时,会出现滚动条
*/
public static void main(String[] args)
{
final Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
FormToolkit formToolkit = new FormToolkit(display);
ScrolledForm scrolledForm = formToolkit.createScrolledForm(shell);
Composite container = scrolledForm.getBody();
GridLayout layout = new GridLayout(1, false);
container.setLayout(layout);
final Label label = new Label(container, SWT.NONE);
label.setLayoutData(new GridData(GridData.FILL_BOTH));
final Image image = new Image(display, "icons/ipod.jpg");
label.setImage(image);
shell.layout();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
if(image!=null)
{
image.dispose();
}
formToolkit.dispose();
}
/*
* 图像可以随canvas拉伸,图像会形变,不会出现滚动条
*/
// public static void main(String[] args) {
// Display display = Display.getDefault();
// Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1,false));
//
// final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
// canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
// final Image image = new Image(display, "icons/ipod.jpg");
// final int srcWidth = image.getImageData().width;
// final int srcHeight = image.getImageData().height;
//
// canvas.addPaintListener(new PaintListener() {
// public void paintControl(PaintEvent e) {
// Rectangle rect = canvas.getClientArea();
// Point p = new Point(rect.width,rect.height);
// e.gc.drawImage(image, 0, 0,srcWidth,srcHeight,0,0,p.x,p.y);
// }
// });
//
// shell.layout();
// shell.open();
// while (!shell.isDisposed()) {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// }
// /*
// * 图像“按比例”随面板大小形变(达到最适合面板效果),不会出现滚动条
// */
// public static void main(String[] args)
// {
// Display display = Display.getDefault();
// Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1, false));
//
// final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
// canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
// final Image image = new Image(display, "icons/ipod.jpg");
// final double srcWidth = image.getImageData().width;
// final double srcHeight = image.getImageData().height;
//
// canvas.addPaintListener(new PaintListener()
// {
// public void paintControl(PaintEvent e)
// {
// Rectangle rect = canvas.getClientArea();
// double areaWidth = rect.width;
// double areaHeight = rect.height;
//
// double xratio = (1.0*areaWidth)/(1.0*srcWidth);
// double yratio = (1.0*areaHeight)/(1.0*srcHeight);
//
// double ratio = xratio>=yratio?yratio:xratio;
//
// double destWidth = srcWidth * ratio;
// double destHeight = srcHeight * ratio;
//
// e.gc.setAntialias(SWT.ON);
// e.gc.drawImage(image, 0,0, (int) srcWidth,(int) srcHeight, 0,0, (int) destWidth,(int) destHeight);
// }
// });
//
// shell.layout();
// shell.open();
// while (!shell.isDisposed())
// {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// }
/*
* 面板大小不变,图形随放大缩小操作形变,会出现滚动条
*/
private static int cnt = 0;
// public static void main(String[] args)
// {
// final Display display = Display.getDefault();
// final Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1, true));
//
// FormToolkit formToolkit = new FormToolkit(display);
// final ScrolledForm scrolledForm = formToolkit.createScrolledForm(shell);
// scrolledForm.setLayoutData(new GridData(GridData.FILL_BOTH));
// Composite container = scrolledForm.getBody();
// container.setLayout(new FillLayout());
//
// final Label label = new Label(container, SWT.NONE);
// label.addMouseListener(new MouseAdapter()
// {
// @Override
// public void mouseUp(MouseEvent e)
// {
// scrolledForm.setFocus();
// }
// });
// final Image image = new Image(display, "icons/ipod.jpg");
// Image img = new Image(display, image.getImageData());
// label.setImage(img);
// final Composite comp = new Composite(shell, SWT.NONE);
// GridLayout layout = new GridLayout(5, false);
// comp.setLayout(layout);
// final Button btn1 = new Button(comp, SWT.PUSH);
// btn1.setText(" 原图 ");
// final Button btn2 = new Button(comp, SWT.PUSH);
// btn2.setText("放大25%");
// final Button btn3 = new Button(comp, SWT.PUSH);
// btn3.setText("缩小25%");
// final Button btn4 = new Button(comp, SWT.PUSH);
// btn4.setText("自适应");
//
// final Label infoLabel = new Label(comp, SWT.NONE);
// infoLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// infoLabel.setText("原图大小");
//
// SelectionListener listener = new SelectionAdapter()
// {
// @Override
// public void widgetSelected(SelectionEvent e)
// {
// Button btn = (Button)e.widget;
// if (btn == btn1)
// {
// cnt = 0;
// btn2.setEnabled(true);
// btn3.setEnabled(true);
// infoLabel.setText("原图");
// Object ratio = infoLabel.getData("ratio");
// if (ratio != null && ratio.equals(1.0))
// {
// return;
// }
// else
// {
// // 主要是为了在多次点击原图/自适应大小时,不至于频繁刷新图
// infoLabel.setData("ratio", new Double(1.0));
// }
// Image img = label.getImage();
// Image img2 = new Image(display, image.getImageData());
// label.setImage(img2);
// scrolledForm.reflow(true);
// img.dispose();
// }
// else if (btn == btn2)// 放大
// {
// if (cnt < 4)
// {
// cnt++;
// infoLabel.setText("图形大小1+(" + cnt + "*25%)");
// infoLabel.setData("ratio", new Double(1.0 + cnt * 0.25));
// }
// else
// {
// return;
// }
//
// Image im = label.getImage();
//
// double width = image.getImageData().width * (0.25 * cnt + 1.0);
// double height = image.getImageData().height * (0.25 * cnt + 1.0);
//
// ImageData imageData = image.getImageData().scaledTo((int)width, (int)height);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
//
// }
// else if (btn == btn3)// 缩小
// {
// if (cnt > -3)
// {
// cnt--;
// infoLabel.setText("图形大小1+(" + cnt + "*25%)");
// infoLabel.setData("ratio", new Double(1.0 + cnt * 0.25));
// }
// else
// {
// return;
// }
//
// Image im = label.getImage();
//
// double width = image.getImageData().width * (1.0 + 0.25 * cnt);
// double height = image.getImageData().height * (1.0 + 0.25 * cnt);
//
// ImageData imageData = image.getImageData().scaledTo((int)width, (int)height);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
// }
// else if (btn == btn4)// 自适应
// {
// infoLabel.setText("图形大小自适应");
// btn2.setEnabled(false);
// btn3.setEnabled(false);
// Image im = label.getImage();
//
// Point p = scrolledForm.getSize();
// double xratio = (1.0 * p.x) / (1.0 * image.getImageData().width);
// double yratio = (1.0 * p.y) / (1.0 * image.getImageData().height);
//
// double ratio = xratio >= yratio ? yratio : xratio;
//
// Object obj = infoLabel.getData("ratio");
// if (obj != null && obj.equals(ratio))
// {
// return;
// }
// else
// {
// infoLabel.setData("ratio", new Double(ratio));
// }
//
// double destWidth = image.getImageData().width * ratio;
// double destHeight = image.getImageData().height * ratio;
//
// ImageData imageData = image.getImageData().scaledTo((int)destWidth, (int)destHeight);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
// }
// }
// };
// btn1.addSelectionListener(listener);
// btn2.addSelectionListener(listener);
// btn3.addSelectionListener(listener);
// btn4.addSelectionListener(listener);
//
// shell.setSize(500, 500);
// shell.layout();
// shell.open();
// while (!shell.isDisposed())
// {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// formToolkit.dispose();
// }
}
图像的滚动
public class ScrollImage
{
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
Image originalImage = null;
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setText("选择一个图片文件或者取消");
String string = dialog.open();
if (string != null)
{
originalImage = new Image(display, string);
}
if (originalImage == null)
{
int width = 150, height = 200;
originalImage = new Image(display, width, height);
GC gc = new GC(originalImage);
gc.fillRectangle(0, 0, width, height);
gc.drawLine(0, 0, width, height);
gc.drawLine(0, height, width, 0);
gc.drawText("默认图片", 10, 10);
gc.dispose();
}
final Image image = originalImage;
final Point origin = new Point(0, 0);
final ScrollBar hBar = shell.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
int hSelection = hBar.getSelection();
int destX = -hSelection - origin.x;
origin.x = -hSelection;
Rectangle rect = image.getBounds();
shell.scroll(destX, 0, 0, 0, rect.width, rect.height, false);
}
});
final ScrollBar vBar = shell.getVerticalBar();
vBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
int vSelection = vBar.getSelection();
int destY = -vSelection - origin.y;
origin.y = -vSelection;
Rectangle rect = image.getBounds();
shell.scroll(0, destY, 0, 0, rect.width, rect.height, false);
}
});
shell.addListener(SWT.Resize, new Listener()
{
public void handleEvent(Event e)
{
Rectangle rect = image.getBounds();
Rectangle client = shell.getClientArea();
hBar.setMaximum(rect.width);
vBar.setMaximum(rect.height);
//绘图面积改变时重新绘制滚动条
hBar.setThumb(Math.min(rect.width, client.width));
vBar.setThumb(Math.min(rect.height, client.height));
//当绘图面积大于图片时,不显示滚动条
if (hBar.getMaximum() == hBar.getThumb())
{
hBar.setVisible(false);
}
else
{
hBar.setVisible(true);
//当绘图面积改变时,重新设定滚动条中键滚动长度(即点击滚动条空白间隙的滚动长度)
hBar.setPageIncrement(hBar.getThumb());
//设定单击滚动条箭头(或是上、下、左、右键)的滚动长度
hBar.setIncrement(50);
}
if (vBar.getMaximum() == vBar.getThumb())
{
vBar.setVisible(false);
}
else
{
vBar.setVisible(true);
vBar.setPageIncrement(vBar.getThumb());
vBar.setIncrement(50);
}
int hPage = rect.width - client.width;
int vPage = rect.height - client.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
if (hSelection >= hPage)
{
if (hPage <= 0)
hSelection = 0;
origin.x = -hSelection;
}
if (vSelection >= vPage)
{
if (vPage <= 0)
vSelection = 0;
origin.y = -vSelection;
}
shell.redraw();
}
});
shell.addListener(SWT.Paint, new Listener()
{
public void handleEvent(Event e)
{
GC gc = e.gc;
gc.drawImage(image, origin.x, origin.y);
Rectangle rect = image.getBounds();
Rectangle client = shell.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);
}
}
});
shell.setSize(200, 150);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
图像的旋转
public class RotateImageExample
{
int oWidth;
int oHeight;
double nAngle;
double absSin;
double absCos;
Device device = null;
Transform transform = null;
GC gc;
static int x = 0;
public Image rotate(Image oImage, int angle)
{
Rectangle imageRectangle = oImage.getBounds();
oWidth = imageRectangle.width;
oHeight = imageRectangle.height;
nAngle = angle * Math.PI / 180.0;// 弧度
absSin = Math.abs(Math.sin(nAngle));
absCos = Math.abs(Math.cos(nAngle));
int nWidth = (int)Math.floor(oHeight * absSin + oWidth * absCos);
int nHeight = (int)Math.floor(oHeight * absCos + oWidth * absSin);
device = oImage.getDevice();
transform = new Transform(device);
transform.translate(oWidth / 2, oHeight / 2);
transform.rotate(angle);
transform.translate(-oWidth / 2, -oHeight / 2);
Image nImage = new Image(device, nWidth, nHeight);
gc = new GC(nImage);
gc.setTransform(transform);
gc.drawImage(oImage, 0, 0);
gc.dispose();
transform.dispose();
return nImage;
}
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shell = new Shell();
shell.setLayout(new FillLayout());
final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
final RotateImageExample rotimg = new RotateImageExample();
final Image image = new Image(Display.getCurrent(), "icons/ipod.jpg");
canvas.addPaintListener(new PaintListener()
{
@Override
public void paintControl(PaintEvent e)
{
Image img = rotimg.rotate(image, rotimg.x);
e.gc.drawImage(img, 0, 0);
img.dispose();
}
});
// shell.addMouseMoveListener(new MouseMoveListener()
// {
// @Override
// public void mouseMove(MouseEvent e)
// {
// r.x += 5;
// canvas.redraw();
// }
// });
canvas.addMouseMoveListener(new MouseMoveListener()
{
@Override
public void mouseMove(MouseEvent e)
{
RotateImageExample.x -= 5;
canvas.redraw();
}
});
shell.open();
shell.layout();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
Java图像格式转换
ImageIO 目前支持一下格式: BMP, JPG,PNG, JPEG, WBMP, GIF
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageIOTest {
public static void main(String args[]) throws IOException {
File inputFile = new File("c:\\11.jpg");
BufferedImage input = ImageIO.read(inputFile);
ImageIO.write(input, "GIF", outputFile);
//ImageIO.write(input, "JPEG", outputFile);
//ImageIO.write(input, "JPG", outputFile);
//ImageIO.write(input, "PNG", outputFile);
}
}
还可以使用JAI(sun公司java advanced imaging,三个重要的jar文件mlibwrapper_jar.jar、jar_codec.jar和jar_core.jar移到你的classpath环境变量指定的目录下。我们推荐把它们放到你的JDK的jre/lib/ext目录下。)jimi(sun公司)。
SWT图像介绍
这部分内容大多是以前从网上找的,出处不记得了,望原版见谅。
SWT Images简介
软件开发人员可以利用 SWT 封装的 Image, ImageData 等类来创建图像、存储图像数据,也可以对存储的图像数据进行各种图像变换。本文将演示如何正确的使用 Image, ImageData 等类,以及如何使图像变灰、变亮/黑、图像旋转、图像拉伸、图片透明叠加、图片反色等相关问题。
下面就来介绍一下 Image 和 ImageData 这两个在 SWT Images 中最重要的类。
类 org.eclipse.swt.graphics.Image 被用来表示可以在设备上显示的图片,可以用方法如GC.drawImage() 或者 Button.setImage() 等来将它显示出来。Image 类提供了几个构造函数,可以完成以下功能:
• 装载一个现有的图象。可以通过传入文件名或者 InputStream 作为参数,但是图象的格式必须是它所支持的格式之(目前 SWT Image 支持 BMP、GIF、JPG、PNG、Windows ICO 等格式)一,否则会抛出 SWTException 异常。
• 构造一个用已经存在的 ImageData 进行初始化的图像。
• 构造一个空图像。可以通过修改其像素值或者向它拷贝一个 SWT 图形上下文的内容 (GC) 来绘制该图像,并且可以指定空图像的大小。
类 org.eclipse.swt.graphics.ImageData 中存储了图像的像素数据信息。 ImageData 是一个包含有关图像大小、调色板、颜色值和透明度等信息的类。我们可以对这些图像像素数据可以直接读或者写操作,这意味着可以通过直接读取或者修改图像的数据,来设置或者取得图像中任何像素或者任何一组像素的颜色值。关于 ImageData ,我们还应当了解以下一些字段:
• width 和 height 指定图像的宽和高。Depth 指定图像的颜色深度。可能的值为 1、2、4、8、16、24 或者 32,指定编码每一个像素的值所使用的比特数。
• alpha 与 alphaData 定义图像的透明度。alpha 定义了图象的全局透明度值,默认值为 -1,并且alphaData 域将被忽略。当 alpha 不等于 -1 时, alphaData 存储了图象的透明度缓冲区,每个像素可以有一个在 0~255 之间的透明度值,数值越大,表示越不透明。值得注意的是,只有部分图象格式具有透明度,例如 GIF 和 PNG。
• palette 包含一个 PaletteData 对象,它存储有关图像的颜色模型的信息。SWT 的颜色模型可以是索引或者直接的,由palette的域 isDirect 来指定。如果颜色模型是索引的,那么 PaletteData 包含颜色索引,可以通过方法 getRGBs() 来获取 RGB 信息。如果它是直接的,那么它包含转换信息,表明应当如何从像素的整数值中提取出颜色 RGB 成分。
• data 包含像素值的字节缓冲区。字节编码的方法取决于所使用的颜色深度。对于一个 8 位的图像,数组中的一个字节正好表示图像中一个像素的值。对于 16 位图像,每一个像素值编码为缓冲区中的两个字节。这两个字节以最低有效字节顺序存储。对于 24 或者 32 位图像,每一个像素值以最高有效位字节顺序编码为缓冲区中的三个或者四个字节。
• bytesPerLine 表明缓冲区中有多少字节用于表示图像中一行像素的所有像素值。由于一个像素可能有多个字节表示,所以 bytesPerLine 可能是字段 width 值的若干倍。也就是说“一个像素扫描行上有多少个字节”,我们知道表示一个像素可能需要1,、3、4…n个字节等(分别对应256灰度图,24位真彩色等),因此,通过bytesPerPixel = bytesPerLine÷n就可以知道,一个扫描行上有多少个像素。我们将bytesPerPixel称为每个像素所占的字节数。
________________________________________
SWT图象处理
常见的图象处理包含图象的读/写、图像变灰、变亮/黑、图像旋转、图像拉伸、图片透明叠加、图片反色等。下面将就这些问题逐个介绍,表 1 列出了各个清单所对应的图像处理。
图像的读写
我们可以使用类 org.eclipse.swt.graphics.ImageLoader 来加载或者保存图像。 ImageLoader 具有一个全局的成员变量 ImageData[],它用于存储图片数据。
清单 1. 图像读写示例
图像可以直接得到
Image image = new Image(display, “e:/aa.jpg”);
我们还可以用ImageLoader得到(不仅能得到,还能保存为各种格式的图像文件,)
ImageLoader loader = new ImageLoader();
ImageData[] imgD = loader.load("icons/ipod.jpg");
if(imgD!=null&&imgD.length>0)
{
image = new Image(display, imgD[0]);
label.setImage(image);
loader.data[0] = image.getImageData();
loader.save("icons/qqq.png", SWT.IMAGE_PNG);
}
图像变灰
图像变灰在桌面应用程序中有着广泛的应用。例如,一个图标被作为一个按钮的背景,我们需要一个灰色效果的图标作为按钮的背景来表示这个按钮处于禁用状态。在SWT中,基于已经存在的图像来创建一个具有灰色效果的图像,我们可以使用构造函数 Image(Display display, Image image, int flag) 来创建,其中参数 flag 使用 SWT.IMAGE_GRAY。
清单 2. 图像变灰示例
Image newImage = new Image(null, image, SWT.IMAGE_GRAY);
图像变亮/变黑
下面讨论图像变亮/变黑。 RGB 和 HSL (也叫 HSB/HSV )是两种色彩空间,即:红、绿、蓝( Red, Green, Blue) 和色调、饱和度、亮度( Hue, Saturation, Lightness 或 Brightness 或 Value),前者适用于机器采样,目前的显示器颜色即由这三种基色构成,而后者更符合人类的直观感觉。在 Windows 的标准颜色对话框中均包含这两种表示方法。 RGB 的取值范围在 0~255 之间, HSL 的取值在 0~1 之间。因此我们只需要将 HSL 空间数据的 L 分量进行调整即可调整此图像的亮度。要实现图像变亮/变黑的功能,只需要调整清单 3 中函数 lightImage 行(*)中等号右边的值( 0 到 1 之间)。
清单 3. 图像变亮示例
private static ImageData lightImage(ImageData srcData) {
double[] data = rgbTohsl(srcData.data);
byte[] newData = new byte[srcData.data.length];
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.width * bytesPerPixel;
for(int i = 0; i < data.length; i += 3) {
data[i + 2] = 0.75; //----------------- (*)
}
data = hslTorgb(data);
for(int i = 0; i < srcData.data.length; i ++) {
newData[i] = (byte)data[i];
}
ImageData newImageData = new ImageData(srcData.width,
srcData.height,
srcData.depth,
srcData.palette,
destBytesPerLine,
newData);
return newImageData;
}
其中,方法 double[] rgbTohsl(byte[] data) 是把 RGB 空间数据转换到 HSL 空间;相反的,方法 double[] hslTorgb(double[] data) 是把数据从 HSL 空间转换到 RGB 空间。
图像旋转
清单4中方法 rotate 实现了将图像相左旋转 90 度。如图 1 ,对于像素点 (x, y) ,向左旋转90 度以后,它在图象中的位置变成了 (y, width - x - 1) 。因此,相左旋转 90 度即将所有的像素点按照规则换一下位置。其他的旋转可用同样的方法。
旋转中心点为图形左下角,旋转90度的计算公式:
X’ = y;
y’= -x;
旋转中心点为图形左上角,旋转90度的计算公式:
X’ = -y;
y’= x;
旋转中心点为图形中心点,坐标为计算机平面坐标(左上角为(0,0)),旋转90度的计算公式:
X’ = y;
y’= width-x-1;
旋转中心点为图形中心点,坐标为左下角为(0,0),旋转90度的计算公式:
X’ = height –y -1;
y’= x;
图1 旋转前与相左旋转 90 度后
清单4. 图像旋转示例
private static ImageData rotate(ImageData srcData) {
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.height * bytesPerPixel;
byte[] newData = new byte[srcData.data.length];
int width = 0, height = 0;
for (int srcY = 0; srcY < srcData.height; srcY++) {
for (int srcX = 0; srcX < srcData.width; srcX++) {
int destX = 0, destY = 0, destIndex = 0, srcIndex = 0;
destX = srcY;
destY = srcData.width - srcX - 1;
width = srcData.height;
height = srcData.width;
destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel);
srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel);
System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel);
}
}
return new ImageData(width, height, srcData.depth, srcData.palette, destBytesPerLine, newData);
}
图像反色
对于彩色图像的 R、G、B 各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理,其算法很简单,假设源图像一像素的红,绿,蓝分量为 (R,G,B),则目标图像该像素的红绿蓝分量应变为 (255 - R,255 - G, 255 - B)。
清单5. 图像反色示例
private static ImageData reverseImage(ImageData srcData)
{
int bytesPerPixel = srcData.bytesPerLine / srcData.width;
int destBytesPerLine = srcData.width * bytesPerPixel;
byte[] newData = srcData.data;
for (int i = 0; i < newData.length; i++)
newData[i] = (byte)(255 - newData[i]);
ImageData newImageData = new ImageData(srcData.width, srcData.height, srcData.depth, srcData.palette, destBytesPerLine, newData);
newImageData.transparentPixel = srcData.transparentPixel;
return newImageData;
}
图像拉伸
图像的缩小/放大一般分为按比例缩小和不按比例缩小两种。图像的缩小操作中,是在现有的信息里如何挑选所需要的有用信息。图像的放大操作中,则需对尺寸放大后所多出来的空格填入适当的值,这是信息的估计问题,所以较图像的缩小要难一些,而且图像大比例放大时经常会出现马赛克效应。庆幸的是,SWT 工具箱对图像的拉伸进行了封装,开发者只需要调用方法 ImageData.scaledTo(int width, int height) 来获得一个拉伸后的 ImageData。
清单6. 图像拉伸示例
Image newImage = new Image(null, imageData[0].scaledTo(imageData[0].width / 2,imageData[0].height / 2));
图片透明叠加
透明叠加方式是图象处理中常用的一种处理方式,在这种处理方式中,一幅图片叠加到另一幅图片上,但是这幅图象不是完全将原来的图象覆盖,而是能够部分的透过叠加的图象显示出来,透明的程度由透明度参数指定(假定为 a,其值在 0 与 1 之间,数值越小表明被叠加的图片越透明),其原理是目标图片的 R、G、B 以及 alpha 分别为待叠加图片A的 R、G、B 以及 alpha 分量乘以透明度参数 a 加上待叠加图片B的 R、G、B 以及 alpha 分量乘以 1-a 的值。我们可以使用图片的透明叠加作出水印的效果。
清单7. 图像透明叠加示例
private static ImageData watermark(ImageData srcData1, ImageData srcData2, double alpha)
{
if (srcData1.width != srcData2.width || srcData1.height != srcData2.height || srcData1.bytesPerLine != srcData2.bytesPerLine)
// 未考虑不同大小图片的叠加
return null;
int bytesPerPixe = srcData1.bytesPerLine / srcData1.width;
int destBytesPerLine = srcData1.width * bytesPerPixe;
byte[] newData = new byte[srcData1.data.length];
ImageData newImageData = new ImageData(srcData1.width, srcData1.height, srcData1.depth, srcData1.palette, destBytesPerLine, newData);
for (int srcY = 0; srcY < srcData1.height; srcY++)
{
for (int srcX = 0; srcX < srcData1.bytesPerLine; srcX++)
{
int idx = srcY * srcData1.bytesPerLine + srcX;
newImageData.data[idx] = (byte)(alpha * srcData1.data[idx] + (1 - alpha) * srcData2.data[idx]);
}
}
return newImageData;
}24位真彩色图转为256色图(灰度图)
彩色图像转换为黑白图像时需要计算图像中每像素有效的亮度值,通过匹配像素亮度值可以轻松转换为黑白图像。
计算像素有效的亮度值可以使用下面的公式:
Y=0.3red+0.59green+0.11blue
然后使用 Color.FromArgb(Y,Y,Y) 来把计算后的值转换
转换代码可以使用下面的方法来实现:
按照以上同样的方法我们有:
public static Image convertToGrayscale(Image source )
{
if(source == null )return null;
ImageData ida = source.getImageData();
byte[] data2 = new byte[ida.data.length];
int offset = 0;
int k = 0;
int r, g,b,gray;
for(int i=0;i<ida.height;i++)
{
for(int j=0;j<ida.width;j++)
{
k = offset+j*3;
b = ida.data[k]&0xff;
g = ida.data[k + 1]&0xff;
r = ida.data[k + 2]&0xff;
gray = (int) (0.11*b + 0.59*g + 0.3*r);
data2[k]=data2[k+1]=data2[k+2]=(byte)gray;
}
offset += ida.bytesPerLine;
}
ImageData ida2 = new ImageData(ida.width, ida.height, ida.depth, ida.palette, ida.scanlinePad, data2);
Return new Image(source.getDevice(),ida2);
}
另外,我们也可以直接利用swt image在new 的时候指定flag来做到:
Image img1 = new Image(display,"E:/资料/小内容/Winter.jpg");
Image img2 = new Image(display,img1,SWT.IMAGE_GRAY);
Image的flag目前共有3个分别是SWT.IMAGE_GRAY, SWT.IMAGE_COPY, SWT.IMAGE_DISABLE。
经过与swt image中生成SWT.IMAGE_GRAY的计算方法。发现上面的清单有问题,具体再查。先这么着吧。
图像旋转/放大/移动的坐标对应
x = 1/ω * [x1*cos θ + y1*sinθ – (x0*cosθ + y0*sinθ)];
y = 1/ω * [y1*cosθ – x1*sinθ – (y0*cosθ - x0*sinθ)];
(x ,y)是原图中的点
(x1,y1)是视图窗口中的点
θ是旋转的角度
ω是放大倍数
(x0,y0)是平移时鼠标移动的偏移量
SWT_Image界面操作
图像拖动
public class DragImage
{
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.H_SCROLL | SWT.V_SCROLL);
final Composite composite = new Composite(shell, SWT.BORDER);
composite.setEnabled(false);
composite.setLayout(new FillLayout());
composite.setSize(700, 600);
final Color red = display.getSystemColor(SWT.COLOR_RED);
composite.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
e.gc.setBackground(red);
e.gc.fillOval(5, 5, 690, 590);
}
});
final ScrollBar hBar = shell.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
Point location = composite.getLocation();
location.x = -hBar.getSelection();
composite.setLocation(location);
}
});
final ScrollBar vBar = shell.getVerticalBar();
vBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
Point location = composite.getLocation();
location.y = -vBar.getSelection();
composite.setLocation(location);
}
});
shell.addListener(SWT.Resize, new Listener()
{
public void handleEvent(Event e)
{
Point size = composite.getSize();
Rectangle rect = shell.getClientArea();
hBar.setMaximum(size.x);
vBar.setMaximum(size.y);
hBar.setThumb(Math.min(size.x, rect.width));
vBar.setThumb(Math.min(size.y, rect.height));
int hPage = size.x - rect.width;
int vPage = size.y - rect.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
Point location = composite.getLocation();
if (hSelection >= hPage)
{
if (hPage <= 0)
hSelection = 0;
location.x = -hSelection;
}
if (vSelection >= vPage)
{
if (vPage <= 0)
vSelection = 0;
location.y = -vSelection;
}
composite.setLocation(location);
}
});
final Point[] offset = new Point[1];
Listener listener = new Listener()
{
public void handleEvent(Event event)
{
switch (event.type)
{
case SWT.MouseDown:
Rectangle rect = composite.getBounds();
if (rect.contains(event.x, event.y))
{
Point pt1 = composite.toDisplay(0, 0);
Point pt2 = shell.toDisplay(event.x, event.y);
offset[0] = new Point(pt2.x - pt1.x, pt2.y - pt1.y);
}
break;
case SWT.MouseMove:
if (offset[0] != null)
{
Point pt = offset[0];
composite.setLocation(event.x - pt.x, event.y - pt.y);
System.out.println("x : " + event.x + " y : " + event.y);
hBar.setSelection(pt.x - event.x);
vBar.setSelection(pt.y - event.y);
}
break;
case SWT.MouseUp:
offset[0] = null;
break;
}
}
};
shell.addListener(SWT.MouseDown, listener);
shell.addListener(SWT.MouseUp, listener);
shell.addListener(SWT.MouseMove, listener);
shell.setSize(600, 500);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
图像的几种显示
public class ImageProcesser
{
/*
* 图像按原始大小显示,当面板尺寸小于图像尺寸时,会出现滚动条
*/
public static void main(String[] args)
{
final Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
FormToolkit formToolkit = new FormToolkit(display);
ScrolledForm scrolledForm = formToolkit.createScrolledForm(shell);
Composite container = scrolledForm.getBody();
GridLayout layout = new GridLayout(1, false);
container.setLayout(layout);
final Label label = new Label(container, SWT.NONE);
label.setLayoutData(new GridData(GridData.FILL_BOTH));
final Image image = new Image(display, "icons/ipod.jpg");
label.setImage(image);
shell.layout();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
if(image!=null)
{
image.dispose();
}
formToolkit.dispose();
}
/*
* 图像可以随canvas拉伸,图像会形变,不会出现滚动条
*/
// public static void main(String[] args) {
// Display display = Display.getDefault();
// Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1,false));
//
// final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
// canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
// final Image image = new Image(display, "icons/ipod.jpg");
// final int srcWidth = image.getImageData().width;
// final int srcHeight = image.getImageData().height;
//
// canvas.addPaintListener(new PaintListener() {
// public void paintControl(PaintEvent e) {
// Rectangle rect = canvas.getClientArea();
// Point p = new Point(rect.width,rect.height);
// e.gc.drawImage(image, 0, 0,srcWidth,srcHeight,0,0,p.x,p.y);
// }
// });
//
// shell.layout();
// shell.open();
// while (!shell.isDisposed()) {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// }
// /*
// * 图像“按比例”随面板大小形变(达到最适合面板效果),不会出现滚动条
// */
// public static void main(String[] args)
// {
// Display display = Display.getDefault();
// Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1, false));
//
// final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
// canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
// final Image image = new Image(display, "icons/ipod.jpg");
// final double srcWidth = image.getImageData().width;
// final double srcHeight = image.getImageData().height;
//
// canvas.addPaintListener(new PaintListener()
// {
// public void paintControl(PaintEvent e)
// {
// Rectangle rect = canvas.getClientArea();
// double areaWidth = rect.width;
// double areaHeight = rect.height;
//
// double xratio = (1.0*areaWidth)/(1.0*srcWidth);
// double yratio = (1.0*areaHeight)/(1.0*srcHeight);
//
// double ratio = xratio>=yratio?yratio:xratio;
//
// double destWidth = srcWidth * ratio;
// double destHeight = srcHeight * ratio;
//
// e.gc.setAntialias(SWT.ON);
// e.gc.drawImage(image, 0,0, (int) srcWidth,(int) srcHeight, 0,0, (int) destWidth,(int) destHeight);
// }
// });
//
// shell.layout();
// shell.open();
// while (!shell.isDisposed())
// {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// }
/*
* 面板大小不变,图形随放大缩小操作形变,会出现滚动条
*/
private static int cnt = 0;
// public static void main(String[] args)
// {
// final Display display = Display.getDefault();
// final Shell shell = new Shell(display);
// shell.setLayout(new GridLayout(1, true));
//
// FormToolkit formToolkit = new FormToolkit(display);
// final ScrolledForm scrolledForm = formToolkit.createScrolledForm(shell);
// scrolledForm.setLayoutData(new GridData(GridData.FILL_BOTH));
// Composite container = scrolledForm.getBody();
// container.setLayout(new FillLayout());
//
// final Label label = new Label(container, SWT.NONE);
// label.addMouseListener(new MouseAdapter()
// {
// @Override
// public void mouseUp(MouseEvent e)
// {
// scrolledForm.setFocus();
// }
// });
// final Image image = new Image(display, "icons/ipod.jpg");
// Image img = new Image(display, image.getImageData());
// label.setImage(img);
// final Composite comp = new Composite(shell, SWT.NONE);
// GridLayout layout = new GridLayout(5, false);
// comp.setLayout(layout);
// final Button btn1 = new Button(comp, SWT.PUSH);
// btn1.setText(" 原图 ");
// final Button btn2 = new Button(comp, SWT.PUSH);
// btn2.setText("放大25%");
// final Button btn3 = new Button(comp, SWT.PUSH);
// btn3.setText("缩小25%");
// final Button btn4 = new Button(comp, SWT.PUSH);
// btn4.setText("自适应");
//
// final Label infoLabel = new Label(comp, SWT.NONE);
// infoLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// infoLabel.setText("原图大小");
//
// SelectionListener listener = new SelectionAdapter()
// {
// @Override
// public void widgetSelected(SelectionEvent e)
// {
// Button btn = (Button)e.widget;
// if (btn == btn1)
// {
// cnt = 0;
// btn2.setEnabled(true);
// btn3.setEnabled(true);
// infoLabel.setText("原图");
// Object ratio = infoLabel.getData("ratio");
// if (ratio != null && ratio.equals(1.0))
// {
// return;
// }
// else
// {
// // 主要是为了在多次点击原图/自适应大小时,不至于频繁刷新图
// infoLabel.setData("ratio", new Double(1.0));
// }
// Image img = label.getImage();
// Image img2 = new Image(display, image.getImageData());
// label.setImage(img2);
// scrolledForm.reflow(true);
// img.dispose();
// }
// else if (btn == btn2)// 放大
// {
// if (cnt < 4)
// {
// cnt++;
// infoLabel.setText("图形大小1+(" + cnt + "*25%)");
// infoLabel.setData("ratio", new Double(1.0 + cnt * 0.25));
// }
// else
// {
// return;
// }
//
// Image im = label.getImage();
//
// double width = image.getImageData().width * (0.25 * cnt + 1.0);
// double height = image.getImageData().height * (0.25 * cnt + 1.0);
//
// ImageData imageData = image.getImageData().scaledTo((int)width, (int)height);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
//
// }
// else if (btn == btn3)// 缩小
// {
// if (cnt > -3)
// {
// cnt--;
// infoLabel.setText("图形大小1+(" + cnt + "*25%)");
// infoLabel.setData("ratio", new Double(1.0 + cnt * 0.25));
// }
// else
// {
// return;
// }
//
// Image im = label.getImage();
//
// double width = image.getImageData().width * (1.0 + 0.25 * cnt);
// double height = image.getImageData().height * (1.0 + 0.25 * cnt);
//
// ImageData imageData = image.getImageData().scaledTo((int)width, (int)height);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
// }
// else if (btn == btn4)// 自适应
// {
// infoLabel.setText("图形大小自适应");
// btn2.setEnabled(false);
// btn3.setEnabled(false);
// Image im = label.getImage();
//
// Point p = scrolledForm.getSize();
// double xratio = (1.0 * p.x) / (1.0 * image.getImageData().width);
// double yratio = (1.0 * p.y) / (1.0 * image.getImageData().height);
//
// double ratio = xratio >= yratio ? yratio : xratio;
//
// Object obj = infoLabel.getData("ratio");
// if (obj != null && obj.equals(ratio))
// {
// return;
// }
// else
// {
// infoLabel.setData("ratio", new Double(ratio));
// }
//
// double destWidth = image.getImageData().width * ratio;
// double destHeight = image.getImageData().height * ratio;
//
// ImageData imageData = image.getImageData().scaledTo((int)destWidth, (int)destHeight);
// Image newIm = new Image(display, imageData);
// label.setImage(newIm);
// scrolledForm.reflow(true);
// im.dispose();
// }
// }
// };
// btn1.addSelectionListener(listener);
// btn2.addSelectionListener(listener);
// btn3.addSelectionListener(listener);
// btn4.addSelectionListener(listener);
//
// shell.setSize(500, 500);
// shell.layout();
// shell.open();
// while (!shell.isDisposed())
// {
// if (!display.readAndDispatch())
// display.sleep();
// }
// image.dispose();
// formToolkit.dispose();
// }
}
图像的滚动
public class ScrollImage
{
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
Image originalImage = null;
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setText("选择一个图片文件或者取消");
String string = dialog.open();
if (string != null)
{
originalImage = new Image(display, string);
}
if (originalImage == null)
{
int width = 150, height = 200;
originalImage = new Image(display, width, height);
GC gc = new GC(originalImage);
gc.fillRectangle(0, 0, width, height);
gc.drawLine(0, 0, width, height);
gc.drawLine(0, height, width, 0);
gc.drawText("默认图片", 10, 10);
gc.dispose();
}
final Image image = originalImage;
final Point origin = new Point(0, 0);
final ScrollBar hBar = shell.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
int hSelection = hBar.getSelection();
int destX = -hSelection - origin.x;
origin.x = -hSelection;
Rectangle rect = image.getBounds();
shell.scroll(destX, 0, 0, 0, rect.width, rect.height, false);
}
});
final ScrollBar vBar = shell.getVerticalBar();
vBar.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
int vSelection = vBar.getSelection();
int destY = -vSelection - origin.y;
origin.y = -vSelection;
Rectangle rect = image.getBounds();
shell.scroll(0, destY, 0, 0, rect.width, rect.height, false);
}
});
shell.addListener(SWT.Resize, new Listener()
{
public void handleEvent(Event e)
{
Rectangle rect = image.getBounds();
Rectangle client = shell.getClientArea();
hBar.setMaximum(rect.width);
vBar.setMaximum(rect.height);
//绘图面积改变时重新绘制滚动条
hBar.setThumb(Math.min(rect.width, client.width));
vBar.setThumb(Math.min(rect.height, client.height));
//当绘图面积大于图片时,不显示滚动条
if (hBar.getMaximum() == hBar.getThumb())
{
hBar.setVisible(false);
}
else
{
hBar.setVisible(true);
//当绘图面积改变时,重新设定滚动条中键滚动长度(即点击滚动条空白间隙的滚动长度)
hBar.setPageIncrement(hBar.getThumb());
//设定单击滚动条箭头(或是上、下、左、右键)的滚动长度
hBar.setIncrement(50);
}
if (vBar.getMaximum() == vBar.getThumb())
{
vBar.setVisible(false);
}
else
{
vBar.setVisible(true);
vBar.setPageIncrement(vBar.getThumb());
vBar.setIncrement(50);
}
int hPage = rect.width - client.width;
int vPage = rect.height - client.height;
int hSelection = hBar.getSelection();
int vSelection = vBar.getSelection();
if (hSelection >= hPage)
{
if (hPage <= 0)
hSelection = 0;
origin.x = -hSelection;
}
if (vSelection >= vPage)
{
if (vPage <= 0)
vSelection = 0;
origin.y = -vSelection;
}
shell.redraw();
}
});
shell.addListener(SWT.Paint, new Listener()
{
public void handleEvent(Event e)
{
GC gc = e.gc;
gc.drawImage(image, origin.x, origin.y);
Rectangle rect = image.getBounds();
Rectangle client = shell.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);
}
}
});
shell.setSize(200, 150);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
图像的旋转
public class RotateImageExample
{
int oWidth;
int oHeight;
double nAngle;
double absSin;
double absCos;
Device device = null;
Transform transform = null;
GC gc;
static int x = 0;
public Image rotate(Image oImage, int angle)
{
Rectangle imageRectangle = oImage.getBounds();
oWidth = imageRectangle.width;
oHeight = imageRectangle.height;
nAngle = angle * Math.PI / 180.0;// 弧度
absSin = Math.abs(Math.sin(nAngle));
absCos = Math.abs(Math.cos(nAngle));
int nWidth = (int)Math.floor(oHeight * absSin + oWidth * absCos);
int nHeight = (int)Math.floor(oHeight * absCos + oWidth * absSin);
device = oImage.getDevice();
transform = new Transform(device);
transform.translate(oWidth / 2, oHeight / 2);
transform.rotate(angle);
transform.translate(-oWidth / 2, -oHeight / 2);
Image nImage = new Image(device, nWidth, nHeight);
gc = new GC(nImage);
gc.setTransform(transform);
gc.drawImage(oImage, 0, 0);
gc.dispose();
transform.dispose();
return nImage;
}
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shell = new Shell();
shell.setLayout(new FillLayout());
final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
final RotateImageExample rotimg = new RotateImageExample();
final Image image = new Image(Display.getCurrent(), "icons/ipod.jpg");
canvas.addPaintListener(new PaintListener()
{
@Override
public void paintControl(PaintEvent e)
{
Image img = rotimg.rotate(image, rotimg.x);
e.gc.drawImage(img, 0, 0);
img.dispose();
}
});
// shell.addMouseMoveListener(new MouseMoveListener()
// {
// @Override
// public void mouseMove(MouseEvent e)
// {
// r.x += 5;
// canvas.redraw();
// }
// });
canvas.addMouseMoveListener(new MouseMoveListener()
{
@Override
public void mouseMove(MouseEvent e)
{
RotateImageExample.x -= 5;
canvas.redraw();
}
});
shell.open();
shell.layout();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
发表评论
-
swt example之画高级图形
2015-05-13 21:36 0高级图形前提 图形能被系统支持。使用图形高级操作之前要检查 ... -
swt 图像数据和分析
2015-05-08 15:18 0图像压缩率 Jpg,jpeg,jfif的图像压缩率从0~ ... -
java swt 画正弦曲线
2014-10-11 14:31 0使用swt画正弦曲线 -
swt中显示动态Bezier曲线
2014-08-15 14:46 0在shell上画动态1,2,3阶贝塞尔曲线,图示为三阶曲 ... -
使用 swt 模拟频谱分析图像显示
2014-08-15 09:12 0测试使用SWT实现类似TTPlayer上频谱分析的图像显 ...
相关推荐
在人工智能领域,Java图像处理类库也扮演着重要角色,尤其是在计算机视觉和机器学习应用中。例如,它们可以用于预处理图像数据,以便于训练深度学习模型。开发者可以利用这些库来提取特征、标注图像、识别物体,甚至...
Java Graphics 2D 是 Java 语言中图形图像处理的 API,提供了图形图像处理的基本功能。 4. Java GUI 概述 Java GUI 是 Java 语言中图形用户界面的解决方案,提供了图形用户界面的设计和实现。Java GUI 能够提供...
5. **Java图像处理库**: 在Java中实现图像处理,可以利用开源库如OpenCV、Java Advanced Imaging (JAI)、JavaFX等。这些库提供了丰富的函数和工具,便于开发人员进行图像读取、显示、转换和处理。 6. **编程实现*...
综上所述,Java图像处理程序模板为开发者提供了便捷的工具,简化了图像处理的实现过程,无论是简单的图像操作还是复杂的图像分析,都可以在这个基础上进行扩展和实现。通过理解和熟练运用上述知识点,你可以根据需求...
Java图像处理主要涉及Java Advanced Imaging (JAI) API和Java Image I/O (JIO) API。JAI API是Sun Microsystems开发的一个高级图像处理工具,它作为Java Media Framework的一部分,为Java 2D API提供了扩展,专门...
在数字图像处理领域,Java是一种常用的编程语言,用于开发各种图像处理算法和应用。本项目主要涉及了几个关键的图像处理技术,包括直方图均衡化、中值滤波、对数变换、模糊处理、锐化、旋转和平移。下面将详细解释...
通过深入学习和实践这些Java图像处理的知识点,开发者可以构建出能处理各种图像任务的应用,无论是简单的图像显示,还是复杂的图像分析和识别,Java都能提供足够的工具和资源。在人工智能和视觉编程领域,熟练掌握...
### 谈Java图像处理技术 #### Java 2D中的图像处理模型 Java 2D是一种用于绘制图形、处理图像的技术框架,它为开发者提供了一系列高级API,使得图像处理变得更加简单高效。Java 2D中的图像处理模型主要采用即时...
本文将重点探讨Java在图像处理中的应用,通过分析提供的"PSDReader.java"源码,我们可以深入理解Java如何处理图像,特别是对Photoshop的PSD文件格式的支持。 在Java中,进行图像处理主要依赖于Java的`java.awt`和`...
在这个“简单的java applet图像移动重画实例”中,我们将深入探讨Java Applet的基础知识,以及如何实现图像的动态移动和重绘。 1. **Java Applet基础知识**: - Java Applet是Java平台的一部分,它通过Java插件在...
Java数字图像水印处理是一种在图像中嵌入隐藏信息的技术,通常用于版权保护、认证或追踪图像来源。在这个基于Eclipse的项目中,开发者利用Java的强大学术和工业支持,构建了一个简单但功能完备的数字水印系统,涵盖...
在开发数字图像处理系统的过程中,Java技术因其跨平台、面向对象、简单易学等特性,成为实现该系统的一种有效工具。Java的Swing库能够用来创建用户界面,实现图像处理结果的可视化。此外,Java环境下的图像处理可以...
通过学习这些源码,你不仅可以了解Java图像处理的基础,还能掌握如何将理论知识应用于实际项目中。 总之,Java为图像处理提供了丰富的工具和库,无论是简单的绘图还是复杂的算法实现,都可以在Java环境中高效地完成...
1. **Java图像处理基础**: Java中的`java.awt`和`javax.imageio`包为开发者提供了基本的图像处理功能。例如,可以使用`BufferedImage`类创建、读取和修改图像。`Graphics2D`子类提供了一套绘图方法,用于在图像上...
然而,对于简单的图像处理任务,Java标准库中的java.awt.image包也足够使用,例如创建BufferedImage对象,进行颜色转换,以及使用Graphics2D类进行绘制。 其次,Java Media Framework (JMF) 是一个用于播放、捕获和...
"JAVA图像处理源码"这个资源提供了一种实现图像识别与处理的方法,帮助我们勾勒出图像中的物体轮廓。下面我们将深入探讨Java中的图像处理技术以及如何实现这些功能。 首先,Java提供了Java Advanced Imaging (JAI)...
在Java编程语言中,图像处理是一项重要的技能,特别是在开发图形用户界面、游戏或者数据分析应用时。上述内容展示了如何使用Java进行基本的图像读取和尺寸获取操作。这里我们将深入探讨这些知识点。 首先,我们看到...
Java 2D API 是一套用于高级二维图形和图像处理的类集合,它涵盖了线条、文本和图像在一个全面的模型之中。此 API 提供了对图像合成以及带有 Alpha 通道的图像支持,并且包含了一系列准确的颜色空间定义和转换类,...
《数字图像处理:Java编程与实验》是一本深入探讨数字图像处理技术的书籍,结合了理论与实践,特别强调了使用...对于学习者来说,通过书中提供的实验和项目,能够深入理解和掌握数字图像处理的原理及其在Java中的实现。
《基于Java的图形图像处理软件的设计与实现》 在当今数字化时代,图形图像处理软件扮演着至关重要的角色,从照片编辑、艺术创作到科学研究,无处不在。本论文主要探讨了如何利用Java语言来设计和实现一款高效、易用...