- 浏览: 752104 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
u011487470:
感觉就是知识采集一样,博主能不能整理一下
基于Web的IM简介 -
whxtbest:
whxtbest 写道2里面:如果T本身就是重复的话 比如 ...
关于后缀树的一些理解 -
whxtbest:
2里面:如果T本身就是重复的话 比如S是aaab,T是aa ...
关于后缀树的一些理解 -
刘亮love小雪:
谢谢啦
Java 2D高级绘图 -
bluky999:
收集的资料挺多的 哈哈
基于Web的IM简介
笔者在这里将画线,画或填充多边形等理解为"图形"技术,将图片的变换,显示理解为"图像"技术.
相对而言,图形技术较简单,图像技术较复杂.下面笔者从实用的角度出发,讲解几个图像编程问题.首先,我们看下面这个程序.
import Java.applet.*;
import java.awt.*;
public class easy extends Applet
{
int i=1;
Image img;
public void init()
{
img=getImage(getCodeBase(),"mama.gif");
}
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
showStatus(String.valueOf(i++));
}
}
HTML 文件如下:
<APPLET CODE="easy.class"WIDTH=300 HEIGHT=300></APPLET>
程序非常简单. 但你注意到没有,在浏览器的状态栏,显示出的数值并不一定是1: 你要显示的图片幅面越大,这个数值越大.这说明 paint() 方法被调用了不止一次.那么,是谁,在什么时候调用的?
事实上,每当有新的图片数据到达或生成时,Java小程序都会自动去调用paint()方法重绘屏幕.这个工作由ImageObserver接口的imageUpdate()方法实现.你可以超越这个imageUpdate()方法,自己重新编程.考虑到本地的机器从Web服务器上获取图片的速度一般比较慢,很多时候你必须要知道已经有多少图片数据已经被下载.下面给出一个示范程序,程序可以一边下载,一边显示,同时通知用户已经获得多少图片数据.
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
public class image_download extends Applet
{
Image img;
int step=0;//step 用来表述已被下载的那部分图片的高度
int percent=0;//percent 用来表述已下载的图片的高度占图片总高度的百分比
public void init()
{
img=getImage(getCodeBase(),"mama.gif");
}
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
}
//下面我们超越本来的imageUpdate()方法.每当有新的图片数据到达(或产生)时此方法会被自动调用
public boolean imageUpdate(Image img_ob,int flags,int x,int y,int width,int height)
{
if(((flags & SOMEBITS)!=0) & (img_ob==img))//判断是否又有新的图像数据都被下载
{
step=step+height;//计算已被下载的图片的高度
percent=step*100/img.getHeight(this);//计算这个高度占图片高度的的百分比
showStatus(percent+"%");//在状态栏显示
repaint(x,y,width,height);//重绘屏幕.但只画新数据表达的部分.简单使用repaint()重绘
//整个屏幕会使画面闪烁
}
if((flags & ERROR)!=0)//假如下载出错
showStatus("image loading error");
if((flags & ALLBITS)!=0)//假如全部图片数据都已下载完
showStatus("Done");
return true;
}
}
HTML文件如下:
<APPLET CODE="image_download.class"WIDTH=300 HEIGHT=300></APPLET>
imageUpdate()参数说明如下:
img_ob: 被监视的图像.
flags: 被监视图像的状态.
ABORT: 图像生成被异常中断
ALLBITS: 全部图像都已生成
ERROR: 发生错误
FRAMEBITS: 完成一幅
HEIGHT: 本次生成的高度
SOMEBITS: 已将生成了一部分图像
WIDTH: 本次生成的宽度
x: x轴坐标
y: y轴坐标
width: 本次下载的图像的宽度
height: 本次下载的图像的高度
下面用两个例子说明怎样获取大幅图像的局部.第一个例子使用CropImageFilter类去获得图像的局部.你可以这样使用这种技术:
首先根据图像裁剪过滤器产生图像过滤器.
ImageFilter filter=new CropImageFilter (int x, int y, int width, int height).
x: 裁剪起始点 X 轴坐标
y: 裁剪起始点Y 轴坐标
width: 裁剪宽度
height: 裁剪高度
然后根据根据过滤器产生图像生产者. ImageProdUCer procuder=new FilteredImageSource(baseImage.getSource(),filter).
baseImage: 将要被裁剪的图片
然后根据图像生产者产生新的图像. Image img=createImage(procuder).
下面的程序使用上述技术裁剪图片.程序运行后,你用"拖拽"鼠标的方式(按住鼠标键并移动鼠标)在图片上选定一片区域,然后再在运行区上点击鼠标,刚才你选定的区域的图片将被复制到这个位置.要注意的是,程序并未对选择区域的起始点和终止点的相对位置作出判断,因此,你一定要使终止点在起始点的右下方.
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
public class CropFilterImage extends Applet
{
Image baseImage,cropImage;//baseImage是原始图片,cropImage是根据选定区域产生的新图片
int sx,sy;//选定区域起始点坐标
int dx=0,dy=0;//要显示新图片的位置
int width,height;//选定区域的宽和高
boolean selected=false;//用来判定现在用户在干什么
public void init()
{
baseImage=getImage(getCodeBase(),"mama.gif");
cropImage=baseImage;
}
public void paint(Graphics g)
{
g.drawImage(baseImage,0,0,this);
g.drawImage(cropImage,dx,dy,this);
}
public boolean mouseDown(Event evt,int x,int y)
{
if(!selected)//假如用户开始选择
{
sx=x;//记下起始点
sy=y;
selected=true;
return true;
}
else//假如用户已经设定了选择区
{
dx=x;
dy=y;
cropImage=cropImage();//裁剪图像
repaint();//重画屏幕
selected=false;
}
return true;
}
public boolean mouseUp(Event evt,int x,int y)
{
if(selected)//用户松开鼠标健表示已确定选择区
{
width=Math.abs(x-sx);
height=Math.abs(y-sy);
getGraphics().drawRect(sx,sy,width,height);
}
return true;
}
public boolean mouseDrag(Event evt,int x,int y)
{
showStatus("from("+sx+","+sy+") to ("+x+","+y+")");
return true;
}
Image cropImage()
{
ImageFilter filter=new CropImageFilter(sx,sy,width,height);//根据图像裁剪过滤器产生过滤器
//下面根据过滤器产生图像生产者
ImageProducer producer=new FilteredImageSource(baseImage.getSource(),filter);
Image img=createImage(producer);//根据图像生产者产生新图像
return img;
}
}
HTML文件如下:
<APPLET CODE="CropFilterImage.class"WIDTH=600 HEIGHT=300></APPLET>
很多情况下上面的方法不实用.比如你想对图片作出某种变换,上面的方法就无能为力了.下面的程序给出更强大的算法:将图像数据取到数组中,再在数组中将需要的数据提取出来,依据这些数据再生成新的图像去显示.设想你有一个幅面大于窗口尺寸的图像要显示,你必须要让用户可以控制窗口的位置,通过移动窗口,浏览
整个图像.程序运行后,你可以用四个光标键移动窗口浏览全部图像.
程序中的关键技术有三个,第一个是PixelGrabber类用于获取图像数据.你可以这样使用:
首先生成一个PixelGrabber实例:
PixelGrabber pg=new PixelGrabber(Image img,int x,int y,int width,int height,int pix[ ],int offset,int scansize)
img: 被取数据的图像
x: 起始点 x 轴坐标
y: 起始点 y 轴坐标
width: 图像宽度
height: 图像高度
pix[ ]: 目标数组
offset: 目标数组的起始地址
scansize: 图像每行点数
然后使用grabPixels( ) 方法取数据:
try { pg.grabPixels( ) ; }
catch ( InterruptedException e) { }
第二个关键技术是使用媒体追踪器MediaTracker监视图像的生成情况.你可以这样使用:
首先生成一个媒体追踪器的实例:
MediaTracker mt=new MediaTracker(this);
然后向其中加入要追踪的图像:
mt.addImage(Image image,int ID)
image是你要追踪的图像, ID是你设定的一个表示这个图像的序号.
然后使用waitForID ( int ID ) 或 waitForAll( ) 等待图像全部生成
try { mt.waitForID(1);}
catch(InterruptedException e){ }
第三个关键技术是使用内存数据(数组)产生图像.你可以这样使用:
createImage(new MemoryImageSource(int width, int height, int pix[ ], int offset, int scanwidth)
width: 欲生成的图像的宽度
heidth: 欲生成的图像的高度
pix[ ]: 数据源
offset: 丛数组的哪里开始使用数据
scanwidth: 图像每行的象素数
程序如下:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class picture_window extends Applet
{
Image img_full,img_window;//img_full是原图像, img_window是从原图像中裁剪的要在窗口中显示的图像
int img_width,img_height;//原始图像的宽和高
int window_width=150,window_height=150;//窗口的宽和高
int window_x=30,window_y=30;//窗口的左上角坐标
int point_img_full,point_img_window;//原始图像数据数组的操作地址和窗口图像数据数组的操作地址
int img_full_data[];//原始图像数据数组.没有初始化是因为现在不知道原始图像的大小
int img_window_data[]=new int[window_width * window_height];//窗口图像数据数组
MediaTracker mt=new MediaTracker(this);//媒体追踪器
PixelGrabber img_full_grabber;//用来获取原始图像的数据
public void init()
{
img_window=createImage(window_width,window_height);//创建窗口图像
img_full=getImage(getCodeBase(),"mama.gif");
//下面要等待直到全部的原始图像数据都被正确载入.否则无法知道原始图像的大小
mt.addImage(img_full,1);//向媒体追踪其中加入要追踪的图像
try{mt.waitForID(1);} // 等待全部数据被正确载入
catch(InterruptedException e){ }
img_width=img_full.getWidth(this);//现在可以获取原始图像的正确信息了.取它的宽和高
img_height=img_full.getHeight(this);
img_full_data=new int[img_width * img_height];//初始化原始图像数据数组
img_full_grabber=new PixelGrabber(img_full,0,0,img_width,img_height,img_full_data,0,img_width);//准备获取图像数据
try{img_full_grabber.grabPixels();}//采集数据
catch(InterruptedException e){ }
get_img_window_data();//生成窗口图像
}
public void paint(Graphics g)
{
g.drawImage(img_window,0,0,this);
}
public void get_img_window_data()
{
point_img_full=window_y * img_width+window_x;//从这个位置开始获取原始图像数据
point_img_window=0;//从这个位置开始向窗口图像数据数组放数据
for(int i=0;i<window_height;i++)//逐行处理
{
for(int j=0;j<window_width;j++)//逐列处理
img_window_data[point_img_window++]=img_full_data[point_img_full++];//取和存
point_img_full=point_img_full+img_width-window_width;//开始处理下一行
}
img_window=createImage(new MemoryImageSource(window_width,window_height,img_window_data,0,window_width));//根据内存数据(数组)生成图像
//等待图像完全生成.否则一边生成一边绘制窗口图像会闪烁.
mt.addImage(img_window,1);
try{mt.waitForID(1);}
catch(InterruptedException e){}
}
//下面的键盘事件方法根据用户的按键重置窗口坐标,再生成图像,再显示
public boolean keyDown(Event e,int key)
{
switch(key)
{
case(Event.UP):
if(window_y>0)
window_y-=1;
break;
case(Event.DOWN):
if(window_y<(img_height-window_height))
window_y+=1;
break;
case(Event.RIGHT):
if(window_x<(img_width-window_width))
window_x+=1;
break;
case(Event.LEFT):
if(window_x>0)
window_x-=1;
break;
default:
break;
}
showStatus(String.valueOf(window_x)+" , "+String.valueOf(window_y));
get_img_window_data();
getGraphics().drawImage(img_window,0,0,this);
return true;
}
}
HTML文件如下:
<APPLET CODE="picture_window.class"WIDTH=150 HEIGHT=150></APPLET>
下面的程序对两个图像进行合成并显示来模拟图像的淡入淡出.程序运行后,每按一次向上键,前景图像就增强一点,每按一次向下键,前景图像就减弱一点.
首先你要了解图像数据.
每个象素点的信息由一个整数表达.整数共32个二进制位,从左向右,分成四个部分,每部分都是8位.
第一部分: Alpha 信息.控制图像显示的强度.下面的程序就是通过调整这个数值控制图像的淡入淡出.
第二部分:红色数据.
第三部分:绿色数据.
第四部分:蓝色数据.
程序使用的方法是:先画背景图像,再在上面画带Alpha数据的前景图像,通过调整Alpha值使前景图像淡入 淡出.
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class alpha extends Applet
{
Image background, foreground;//背景图像和前景图像
Image foreground_new;//依据前景图像生成的带Alpha通道的新图像
MediaTracker mt;
int foreground_alpha=175;//前景图像的起始Alpha值
int foreground_data[];//用来生成新图像的内存数据
PixelGrabber pg;
int transparancy;//前景图像的全透明点的像素值.只要前景图像的某个点是这个值,它就全透明
public void init()
{
background=getImage(getCodeBase(),"mama.gif");
foreground=getImage(getCodeBase(),"baba.gif");
mt=new MediaTracker(this);
mt.addImage(background,1);
mt.addImage(foreground,2);
try{mt.waitForAll();} // 等待所有图片的数据都被正确载入
catch(InterruptedException e){ }
foreground_data=new int[foreground.getWidth(this) * foreground.getHeight(this)];//初始化
//下面把前景图片的数据载入数组
pg=new PixelGrabber(foreground,0,0,foreground.getWidth(this),foreground.getHeight(this),foreground_data,0,foreground.getWidth(this));
try{pg.grabPixels();}
catch(InterruptedException e){ }
for (int i=0;i<(foreground.getWidth(this) * foreground.getHeight(this));i++)
foreground_data[i]=foreground_data[i]&0x00ffffff;//把所有的象素的Alpha值置为0
//下面我把图像左上角的点的值作为透明值.假如图像中哪个点的值和左上角的点的值一样,
//这个点就全透明--背景100%出现.我用这个比较简单的办法把前景图像中我不想要的部分去掉
transparancy=foreground_data[0];
}
public void paint(Graphics g)
{
g.drawImage(background,0,0,this);
}
public boolean keyDown(Event e, int key)
{
if (key==Event.UP && foreground_alpha<255)//依据按键改变Alpha值
foreground_alpha++;
if (key==Event.DOWN && foreground_alpha>0)
foreground_alpha--;
showStatus(String.valueOf(foreground_alpha));//在状态栏显示Alpha值
for (int i=0;i<(foreground.getWidth(this) * foreground.getHeight(this));i++)//逐点处理
{
foreground_data[i]=foreground_data[i] & 0x00ffffff;//置此点为全透明
if (foreground_data[i]!=transparancy)//假如这个点的值和全透明点不同
foreground_data[i]=foreground_data[i] (foreground_alpha<<24);//给它Alpha值
}
foreground_new=createImage(new MemoryImageSource(foreground.getWidth(this),foreground.getHeight(this),foreground_data,0,foreground.getWidth(this)));//生成前景图象
mt.addImage(foreground_new,3);
try{mt.waitForID(3);}
catch(InterruptedException e2){ }
getGraphics().drawImage(background,0,0,this);//先画背景
getGraphics().drawImage(foreground_new,100,100,this);//再画前景
return true;
}
}
下面是HTML文件:
<APPLET CODE="alpha.class"WIDTH=300 HEIGHT=300></APPLET>
相对而言,图形技术较简单,图像技术较复杂.下面笔者从实用的角度出发,讲解几个图像编程问题.首先,我们看下面这个程序.
import Java.applet.*;
import java.awt.*;
public class easy extends Applet
{
int i=1;
Image img;
public void init()
{
img=getImage(getCodeBase(),"mama.gif");
}
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
showStatus(String.valueOf(i++));
}
}
HTML 文件如下:
<APPLET CODE="easy.class"WIDTH=300 HEIGHT=300></APPLET>
程序非常简单. 但你注意到没有,在浏览器的状态栏,显示出的数值并不一定是1: 你要显示的图片幅面越大,这个数值越大.这说明 paint() 方法被调用了不止一次.那么,是谁,在什么时候调用的?
事实上,每当有新的图片数据到达或生成时,Java小程序都会自动去调用paint()方法重绘屏幕.这个工作由ImageObserver接口的imageUpdate()方法实现.你可以超越这个imageUpdate()方法,自己重新编程.考虑到本地的机器从Web服务器上获取图片的速度一般比较慢,很多时候你必须要知道已经有多少图片数据已经被下载.下面给出一个示范程序,程序可以一边下载,一边显示,同时通知用户已经获得多少图片数据.
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
public class image_download extends Applet
{
Image img;
int step=0;//step 用来表述已被下载的那部分图片的高度
int percent=0;//percent 用来表述已下载的图片的高度占图片总高度的百分比
public void init()
{
img=getImage(getCodeBase(),"mama.gif");
}
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
}
//下面我们超越本来的imageUpdate()方法.每当有新的图片数据到达(或产生)时此方法会被自动调用
public boolean imageUpdate(Image img_ob,int flags,int x,int y,int width,int height)
{
if(((flags & SOMEBITS)!=0) & (img_ob==img))//判断是否又有新的图像数据都被下载
{
step=step+height;//计算已被下载的图片的高度
percent=step*100/img.getHeight(this);//计算这个高度占图片高度的的百分比
showStatus(percent+"%");//在状态栏显示
repaint(x,y,width,height);//重绘屏幕.但只画新数据表达的部分.简单使用repaint()重绘
//整个屏幕会使画面闪烁
}
if((flags & ERROR)!=0)//假如下载出错
showStatus("image loading error");
if((flags & ALLBITS)!=0)//假如全部图片数据都已下载完
showStatus("Done");
return true;
}
}
HTML文件如下:
<APPLET CODE="image_download.class"WIDTH=300 HEIGHT=300></APPLET>
imageUpdate()参数说明如下:
img_ob: 被监视的图像.
flags: 被监视图像的状态.
ABORT: 图像生成被异常中断
ALLBITS: 全部图像都已生成
ERROR: 发生错误
FRAMEBITS: 完成一幅
HEIGHT: 本次生成的高度
SOMEBITS: 已将生成了一部分图像
WIDTH: 本次生成的宽度
x: x轴坐标
y: y轴坐标
width: 本次下载的图像的宽度
height: 本次下载的图像的高度
下面用两个例子说明怎样获取大幅图像的局部.第一个例子使用CropImageFilter类去获得图像的局部.你可以这样使用这种技术:
首先根据图像裁剪过滤器产生图像过滤器.
ImageFilter filter=new CropImageFilter (int x, int y, int width, int height).
x: 裁剪起始点 X 轴坐标
y: 裁剪起始点Y 轴坐标
width: 裁剪宽度
height: 裁剪高度
然后根据根据过滤器产生图像生产者. ImageProdUCer procuder=new FilteredImageSource(baseImage.getSource(),filter).
baseImage: 将要被裁剪的图片
然后根据图像生产者产生新的图像. Image img=createImage(procuder).
下面的程序使用上述技术裁剪图片.程序运行后,你用"拖拽"鼠标的方式(按住鼠标键并移动鼠标)在图片上选定一片区域,然后再在运行区上点击鼠标,刚才你选定的区域的图片将被复制到这个位置.要注意的是,程序并未对选择区域的起始点和终止点的相对位置作出判断,因此,你一定要使终止点在起始点的右下方.
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
public class CropFilterImage extends Applet
{
Image baseImage,cropImage;//baseImage是原始图片,cropImage是根据选定区域产生的新图片
int sx,sy;//选定区域起始点坐标
int dx=0,dy=0;//要显示新图片的位置
int width,height;//选定区域的宽和高
boolean selected=false;//用来判定现在用户在干什么
public void init()
{
baseImage=getImage(getCodeBase(),"mama.gif");
cropImage=baseImage;
}
public void paint(Graphics g)
{
g.drawImage(baseImage,0,0,this);
g.drawImage(cropImage,dx,dy,this);
}
public boolean mouseDown(Event evt,int x,int y)
{
if(!selected)//假如用户开始选择
{
sx=x;//记下起始点
sy=y;
selected=true;
return true;
}
else//假如用户已经设定了选择区
{
dx=x;
dy=y;
cropImage=cropImage();//裁剪图像
repaint();//重画屏幕
selected=false;
}
return true;
}
public boolean mouseUp(Event evt,int x,int y)
{
if(selected)//用户松开鼠标健表示已确定选择区
{
width=Math.abs(x-sx);
height=Math.abs(y-sy);
getGraphics().drawRect(sx,sy,width,height);
}
return true;
}
public boolean mouseDrag(Event evt,int x,int y)
{
showStatus("from("+sx+","+sy+") to ("+x+","+y+")");
return true;
}
Image cropImage()
{
ImageFilter filter=new CropImageFilter(sx,sy,width,height);//根据图像裁剪过滤器产生过滤器
//下面根据过滤器产生图像生产者
ImageProducer producer=new FilteredImageSource(baseImage.getSource(),filter);
Image img=createImage(producer);//根据图像生产者产生新图像
return img;
}
}
HTML文件如下:
<APPLET CODE="CropFilterImage.class"WIDTH=600 HEIGHT=300></APPLET>
很多情况下上面的方法不实用.比如你想对图片作出某种变换,上面的方法就无能为力了.下面的程序给出更强大的算法:将图像数据取到数组中,再在数组中将需要的数据提取出来,依据这些数据再生成新的图像去显示.设想你有一个幅面大于窗口尺寸的图像要显示,你必须要让用户可以控制窗口的位置,通过移动窗口,浏览
整个图像.程序运行后,你可以用四个光标键移动窗口浏览全部图像.
程序中的关键技术有三个,第一个是PixelGrabber类用于获取图像数据.你可以这样使用:
首先生成一个PixelGrabber实例:
PixelGrabber pg=new PixelGrabber(Image img,int x,int y,int width,int height,int pix[ ],int offset,int scansize)
img: 被取数据的图像
x: 起始点 x 轴坐标
y: 起始点 y 轴坐标
width: 图像宽度
height: 图像高度
pix[ ]: 目标数组
offset: 目标数组的起始地址
scansize: 图像每行点数
然后使用grabPixels( ) 方法取数据:
try { pg.grabPixels( ) ; }
catch ( InterruptedException e) { }
第二个关键技术是使用媒体追踪器MediaTracker监视图像的生成情况.你可以这样使用:
首先生成一个媒体追踪器的实例:
MediaTracker mt=new MediaTracker(this);
然后向其中加入要追踪的图像:
mt.addImage(Image image,int ID)
image是你要追踪的图像, ID是你设定的一个表示这个图像的序号.
然后使用waitForID ( int ID ) 或 waitForAll( ) 等待图像全部生成
try { mt.waitForID(1);}
catch(InterruptedException e){ }
第三个关键技术是使用内存数据(数组)产生图像.你可以这样使用:
createImage(new MemoryImageSource(int width, int height, int pix[ ], int offset, int scanwidth)
width: 欲生成的图像的宽度
heidth: 欲生成的图像的高度
pix[ ]: 数据源
offset: 丛数组的哪里开始使用数据
scanwidth: 图像每行的象素数
程序如下:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class picture_window extends Applet
{
Image img_full,img_window;//img_full是原图像, img_window是从原图像中裁剪的要在窗口中显示的图像
int img_width,img_height;//原始图像的宽和高
int window_width=150,window_height=150;//窗口的宽和高
int window_x=30,window_y=30;//窗口的左上角坐标
int point_img_full,point_img_window;//原始图像数据数组的操作地址和窗口图像数据数组的操作地址
int img_full_data[];//原始图像数据数组.没有初始化是因为现在不知道原始图像的大小
int img_window_data[]=new int[window_width * window_height];//窗口图像数据数组
MediaTracker mt=new MediaTracker(this);//媒体追踪器
PixelGrabber img_full_grabber;//用来获取原始图像的数据
public void init()
{
img_window=createImage(window_width,window_height);//创建窗口图像
img_full=getImage(getCodeBase(),"mama.gif");
//下面要等待直到全部的原始图像数据都被正确载入.否则无法知道原始图像的大小
mt.addImage(img_full,1);//向媒体追踪其中加入要追踪的图像
try{mt.waitForID(1);} // 等待全部数据被正确载入
catch(InterruptedException e){ }
img_width=img_full.getWidth(this);//现在可以获取原始图像的正确信息了.取它的宽和高
img_height=img_full.getHeight(this);
img_full_data=new int[img_width * img_height];//初始化原始图像数据数组
img_full_grabber=new PixelGrabber(img_full,0,0,img_width,img_height,img_full_data,0,img_width);//准备获取图像数据
try{img_full_grabber.grabPixels();}//采集数据
catch(InterruptedException e){ }
get_img_window_data();//生成窗口图像
}
public void paint(Graphics g)
{
g.drawImage(img_window,0,0,this);
}
public void get_img_window_data()
{
point_img_full=window_y * img_width+window_x;//从这个位置开始获取原始图像数据
point_img_window=0;//从这个位置开始向窗口图像数据数组放数据
for(int i=0;i<window_height;i++)//逐行处理
{
for(int j=0;j<window_width;j++)//逐列处理
img_window_data[point_img_window++]=img_full_data[point_img_full++];//取和存
point_img_full=point_img_full+img_width-window_width;//开始处理下一行
}
img_window=createImage(new MemoryImageSource(window_width,window_height,img_window_data,0,window_width));//根据内存数据(数组)生成图像
//等待图像完全生成.否则一边生成一边绘制窗口图像会闪烁.
mt.addImage(img_window,1);
try{mt.waitForID(1);}
catch(InterruptedException e){}
}
//下面的键盘事件方法根据用户的按键重置窗口坐标,再生成图像,再显示
public boolean keyDown(Event e,int key)
{
switch(key)
{
case(Event.UP):
if(window_y>0)
window_y-=1;
break;
case(Event.DOWN):
if(window_y<(img_height-window_height))
window_y+=1;
break;
case(Event.RIGHT):
if(window_x<(img_width-window_width))
window_x+=1;
break;
case(Event.LEFT):
if(window_x>0)
window_x-=1;
break;
default:
break;
}
showStatus(String.valueOf(window_x)+" , "+String.valueOf(window_y));
get_img_window_data();
getGraphics().drawImage(img_window,0,0,this);
return true;
}
}
HTML文件如下:
<APPLET CODE="picture_window.class"WIDTH=150 HEIGHT=150></APPLET>
下面的程序对两个图像进行合成并显示来模拟图像的淡入淡出.程序运行后,每按一次向上键,前景图像就增强一点,每按一次向下键,前景图像就减弱一点.
首先你要了解图像数据.
每个象素点的信息由一个整数表达.整数共32个二进制位,从左向右,分成四个部分,每部分都是8位.
第一部分: Alpha 信息.控制图像显示的强度.下面的程序就是通过调整这个数值控制图像的淡入淡出.
第二部分:红色数据.
第三部分:绿色数据.
第四部分:蓝色数据.
程序使用的方法是:先画背景图像,再在上面画带Alpha数据的前景图像,通过调整Alpha值使前景图像淡入 淡出.
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class alpha extends Applet
{
Image background, foreground;//背景图像和前景图像
Image foreground_new;//依据前景图像生成的带Alpha通道的新图像
MediaTracker mt;
int foreground_alpha=175;//前景图像的起始Alpha值
int foreground_data[];//用来生成新图像的内存数据
PixelGrabber pg;
int transparancy;//前景图像的全透明点的像素值.只要前景图像的某个点是这个值,它就全透明
public void init()
{
background=getImage(getCodeBase(),"mama.gif");
foreground=getImage(getCodeBase(),"baba.gif");
mt=new MediaTracker(this);
mt.addImage(background,1);
mt.addImage(foreground,2);
try{mt.waitForAll();} // 等待所有图片的数据都被正确载入
catch(InterruptedException e){ }
foreground_data=new int[foreground.getWidth(this) * foreground.getHeight(this)];//初始化
//下面把前景图片的数据载入数组
pg=new PixelGrabber(foreground,0,0,foreground.getWidth(this),foreground.getHeight(this),foreground_data,0,foreground.getWidth(this));
try{pg.grabPixels();}
catch(InterruptedException e){ }
for (int i=0;i<(foreground.getWidth(this) * foreground.getHeight(this));i++)
foreground_data[i]=foreground_data[i]&0x00ffffff;//把所有的象素的Alpha值置为0
//下面我把图像左上角的点的值作为透明值.假如图像中哪个点的值和左上角的点的值一样,
//这个点就全透明--背景100%出现.我用这个比较简单的办法把前景图像中我不想要的部分去掉
transparancy=foreground_data[0];
}
public void paint(Graphics g)
{
g.drawImage(background,0,0,this);
}
public boolean keyDown(Event e, int key)
{
if (key==Event.UP && foreground_alpha<255)//依据按键改变Alpha值
foreground_alpha++;
if (key==Event.DOWN && foreground_alpha>0)
foreground_alpha--;
showStatus(String.valueOf(foreground_alpha));//在状态栏显示Alpha值
for (int i=0;i<(foreground.getWidth(this) * foreground.getHeight(this));i++)//逐点处理
{
foreground_data[i]=foreground_data[i] & 0x00ffffff;//置此点为全透明
if (foreground_data[i]!=transparancy)//假如这个点的值和全透明点不同
foreground_data[i]=foreground_data[i] (foreground_alpha<<24);//给它Alpha值
}
foreground_new=createImage(new MemoryImageSource(foreground.getWidth(this),foreground.getHeight(this),foreground_data,0,foreground.getWidth(this)));//生成前景图象
mt.addImage(foreground_new,3);
try{mt.waitForID(3);}
catch(InterruptedException e2){ }
getGraphics().drawImage(background,0,0,this);//先画背景
getGraphics().drawImage(foreground_new,100,100,this);//再画前景
return true;
}
}
下面是HTML文件:
<APPLET CODE="alpha.class"WIDTH=300 HEIGHT=300></APPLET>
发表评论
-
Saving JFreeChart as SVG vector images using Batik
2008-07-28 15:52 1751JFreeChart is a free Java class ... -
JfreeChart的使用
2008-07-28 13:42 1327先从网上找点介绍。 一、简介 WW 的发展使得基于 ... -
JPanel绘制的东西如何保存成图像
2008-07-28 10:40 3281[/color][color=darkred][color=d ... -
使用Java Servlet动态生成图片
2008-07-24 16:03 1968在Web应用中,经常需要动态生成图片,比如实时股市行情,各种统 ... -
Java解析JSON
2008-06-10 21:00 27782jsp文件 var people = { "pr ... -
Grizzly和comet介绍(译)
2008-06-10 20:59 2875感觉不是什么新技术,也不是什么新创意,可是一旦用起来可能对技术 ... -
DWR2.1 API Doc
2008-05-19 15:50 1236http://getahead.org/dwr-javadoc ... -
servlet/jsp 获取绝对路径和相对路径
2008-05-14 11:03 3136根目录所对应的绝对路径:request.getServletP ... -
load-on-startup作用
2008-05-14 10:53 2340load-on-startup 元素在web应 ... -
使用异步Servlet扩展AJAX应用程序
2008-05-12 23:30 1312作为Web应用程序模型的A ... -
关于Java的java.library.path
2008-04-30 00:37 16875java可以通过System.getProperty获得系统变 ... -
【转】JNI
2008-04-29 23:50 1363JNI是Java Native Interface的缩写。从J ... -
jni.h所在位置
2008-04-29 23:19 5180在%java_home%\include\下 -
servlet重定向
2008-04-23 14:20 9899在servlet/JSP编程中,服务器端重定向可以通过下面两个 ... -
CVS与Eclipse使用摘要
2008-04-16 17:08 22031. 在administrator下安装CVSNT版本,重启计 ... -
ServletContext和ServletConfig深度分析
2008-04-09 14:00 1345对于web容器来说,ServletContext接口定义了一个 ... -
JSP文件在浏览器中显示出现乱码的解决方法
2008-04-02 10:29 1759采用utf-8编码,在jsp文件中,加入下面2句即可: < ... -
GlassFish
2008-03-20 18:32 1529GlassFish社团正在开发一个免费,开源的Java EE5 ... -
jndi与jdbc的区别
2008-03-20 15:59 2774jndi给所有的命名目录服务提供统一的API前端,jdbc给所 ... -
Tomcat5.5下配置JNDI JDBC数据源
2008-03-20 15:57 14761 安装JDBC驱动 通常,将JDBC驱动安 ...
相关推荐
Java OCR(Optical Character Recognition,光学字符识别)技术是一种计算机视觉领域的应用,它能将图像中的文字转换成可编辑的文本格式。这项技术在各种场景下都有广泛应用,比如文档扫描、车牌识别、发票处理等。...
本文将详细介绍一个具体的Java图像识别技术实例,该实例使用Java实现了一个简单的图像识别算法,主要针对特定数字组合进行识别。 #### 二、项目背景及目标 本项目的目的是开发一个基于Java的图像识别系统,能够...
Java图片识别技术是一种基于计算机视觉和机器学习的领域,它主要涉及如何在图像数据中提取特征并进行比较,以便找到相似或匹配的图片。在Java中实现图片识别,通常会用到OpenCV、Tesseract OCR、JavaFX以及深度学习...
在Java编程语言中,处理图片是一项常见的任务,可以包括添加水印、缩放、裁剪等操作。在提供的代码段中,我们看到一个名为`ImageUtils`...这些都是Java图形处理的基本技术,对于开发涉及图像编辑和处理的应用非常有用。
### 谈Java图像处理技术 #### Java 2D中的图像处理模型 Java 2D是一种用于绘制图形、处理图像的技术框架,它为开发者提供了一系列高级API,使得图像处理变得更加简单高效。Java 2D中的图像处理模型主要采用即时...
ImageComparerUI——基于Java语言实现的相似图像识别,基于直方图比较算法。 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font...
### Java图像识别技术实例教程知识点解析 #### 一、Java图像识别基础概念 在Java中进行图像识别是一项涉及计算机视觉领域的技术应用。本教程主要介绍了如何利用Java的标准库中的`BufferedImage`和`ImageIO`类来...
去除水印可能涉及频域分析、图像增强或机器学习技术,如深度学习网络,以尽可能地恢复原始图像的无水印状态。 在Java中实现这些算法,开发者可能需要编写自定义的图像处理函数,或者利用现有的开源库,如OpenCV for...
在Java编程语言中,图像处理是一项重要的功能,可以用于创建、编辑或操作图像。本教程将探讨两个关键的图像处理技术:模糊处理和锐化处理。这些技术在图像分析、图像增强以及艺术创作中有着广泛的应用。 模糊处理是...
在IT行业中,图片防篡改是一项重要的安全技术,主要用于保护图像数据不被恶意修改。Java作为广泛应用的编程语言,提供了丰富的库和工具来实现这样的功能。在这个项目中,我们主要探讨如何利用Java实现图片的防篡改...
综上所述,"java图片浏览管理系统"是一个集成了多种Java技术的项目,涵盖了从基础编程到高级GUI设计的多个方面。它展示了如何利用Java的强大力量来解决实际问题,对于学习和实践Java开发的开发者来说,是一个很好的...
在Java编程领域,将文字转换为图片是一种常见的需求,它广泛应用于...总之,Java中的文字转图片功能通过结合`Graphics2D`、`BufferedImage`、`Font`等类,可以实现各种定制化的文本图像生成,满足不同的应用场景。
在这个名为"java指纹识别-图片识别技术"的项目工程中,开发者可能利用Java语言实现了指纹图像的处理和比对功能。下面将详细阐述这两个技术以及它们在Java环境中的应用。 首先,我们来看指纹识别技术。指纹是人类...
该技术涉及到多种知识点,包括Tesseract-OCR简介、Java调用Tesseract-OCR、ImageIOHelper类、图片文件转换为tif格式、图像处理技术、Java Advanced Imaging(JAI)和Java Image I/O(JIIO)。该技术具有很高的应用...
在Java中进行图像识别,...总的来说,Java图像识别并判断两图相似性涉及到多个层次的技术,从简单的像素比对到复杂的深度学习模型。开发者可以根据具体需求和环境选择合适的方法,并利用现有的开源工具简化实现过程。
总之,这个项目展示了如何在Java环境下利用JavaCV和OpenCV实现图像拼接,涉及到计算机视觉的基本概念和技术,包括图像处理、特征匹配、几何变换和图像融合。对于想深入学习图像处理和计算机视觉的开发者来说,这是一...
本主题聚焦于"java图像处理编程技术与实践",是面向已经掌握Java基础,尤其是Swing框架的开发者们的一份高等教材。下面将详细探讨这一领域的关键知识点。 首先,Java中的图像处理主要依赖于`java.awt`和`javax....
Java 图像处理是使用 Java 语言对图像进行处理和操作的技术。该技术广泛应用于图像编辑、图像识别、计算机视觉等领域。 在 Java 中,对图像的处理可以通过使用 Java 2D API、Java Advanced Imaging(JAI)等技术来...