返回顶部
首页 > 资讯 > 精选 >Java图像技术(转)
  • 637
分享到

Java图像技术(转)

2023-06-03 05:06:51 637人浏览 泡泡鱼
摘要

笔者在这里将画线,画或填充多边形等理解为"图形"技术,将图片的变换,显示理解为"图像"技术.相对而言,图形技术较简单,图像技术较复杂.下面笔者从实用的角度出发,讲解几个图像编程问题.首先,我们看下面这个程序.import java.appl

笔者在这里将画线,画或填充多边形等理解为"图形"技术,将图片的变换,显示理解为"图像"技术.

相对而言,图形技术较简单,图像技术较复杂.下面笔者从实用的角度出发,讲解几个图像编程问题.首先,我们看下面这个程序.

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 文件如下:



程序非常简单. 但你注意到没有,在浏览器的状态栏,显示出的数值并不一定是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文件如下:



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文件如下:



 

很多情况下上面的方法不实用.比如你想对图片作出某种变换,上面的方法就无能为力了.下面的程序给出更强大的算法:将图像数据取到数组中,再在数组中将需要的数据提取出来,依据这些数据再生成新的图像去显示.设想你有一个幅面大于窗口尺寸的图像要显示,你必须要让用户可以控制窗口的位置,通过移动窗口,浏览

整个图像.程序运行后,你可以用四个光标键移动窗口浏览全部图像.

程序中的关键技术有三个,第一个是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
{

for(int j=0;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文件如下:



 

下面的程序对两个图像进行合成并显示来模拟图像的淡入淡出.程序运行后,每按一次向上键,前景图像就增强一点,每按一次向下键,前景图像就减弱一点.

首先你要了解图像数据.

每个象素点的信息由一个整数表达.整数共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文件:


 [@more@]

--结束END--

本文标题: Java图像技术(转)

本文链接: https://www.lsjlt.com/news/233149.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java图像技术(转)
    笔者在这里将画线,画或填充多边形等理解为"图形"技术,将图片的变换,显示理解为"图像"技术.相对而言,图形技术较简单,图像技术较复杂.下面笔者从实用的角度出发,讲解几个图像编程问题.首先,我们看下面这个程序.import java.appl...
    99+
    2023-06-03
  • java图像识别技术怎么应用
    Java图像识别技术可以应用于多个领域,包括但不限于以下几个方面: 人脸识别:可以使用Java图像识别库来开发人脸识别系统,用于...
    99+
    2023-10-27
    java
  • JAVA声音技术(转)
    声音可以创造意境,触发遐想,当与虚拟图像相结合时,更加可以让整个世界充满幻觉。声音是多媒体技术的基础。这就是Sun公司的JAVA媒体技术开发小组忙于准备Java Sound 1.0 API并将其包含于下一版本的JAVA开发工具库中的原因。 ...
    99+
    2023-06-03
  • Python的图像色彩空间转换技术是什么
    Python中的图像色彩空间转换技术是使用OpenCV库中的cv2.cvtColor()函数来实现的。该函数可以将图像从一种色彩空间...
    99+
    2024-04-29
    Python
  • 转:Java同步技术 (一)
    本文版权归作者Ian Gao所有,如有转载请与作者联系并注明出处http://blog.csdn.net/Iangao/archive/2008/10/09/3041265.aspx。 一、基本同步原理 1 同步机制(synchronize...
    99+
    2023-06-03
  • HTML5 画布标签的图形变换技巧:玩转图像变形艺术
    HTML5画布标签是一个强大的图形API,它允许我们在网页中创建和操纵图形对象。画布标签提供了丰富的图形变换API,包括平移、缩放、旋转和倾斜,这些变换可以应用于任何画布对象,如图像、文本和形状。通过这些变换,我们可以实现各种图像变形效...
    99+
    2024-02-25
    HTML5 画布标签 图形变换 平移 缩放 旋转 倾斜 图像变形
  • Torch中的图像增强技术有哪些
    随机水平翻转:通过随机地在图像水平方向翻转图像来增强数据。 随机垂直翻转:通过在图像垂直方向上随机翻转图像来增强数据。 随机旋转:...
    99+
    2024-04-02
  • CSS图像替换技术方案有哪几种
    这篇文章主要讲解了“CSS图像替换技术方案有哪几种”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS图像替换技术方案有哪几种”吧!Levin的方案:Lev...
    99+
    2024-04-02
  • Linux中如何将图像转换成ASCII艺术
    这篇文章给大家分享的是有关Linux中如何将图像转换成ASCII艺术的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。你知道 什么是 ASCII 么?它是一个标准,在 8 位码中的 256 个空位上分配字母、数字和其...
    99+
    2023-06-27
  • java指南之使用图形:使用图像(转)
    使用图像 这是一个图像: 下面的几页将提供使用图像所需要的详细资料,你将学会如何加载、显示和操纵它们。---------------------------------------------------------------------...
    99+
    2023-06-03
  • Python实例解析图像形态学运算技术
    1 图像形态学运算 在Python OpenCV图像处理之图像滤波特效详解中我们将图像滤波进行了以下分类: 邻域滤波 线性滤波 非线性滤波 频域滤波 ...
    99+
    2024-04-02
  • 利用python设计图像加密技术(Arnold算法)
    目录1、加密算法要求2、Arnold置乱原理3、python实现4、结果分析与总结下面展示了图像的加密和解密过程(左边是输入图像,中间是加密后的结果,右边是解密后的图像): 1、加...
    99+
    2024-04-02
  • 详解在OpenCV中实现的图像标注技术
    目录目录图像注解对图片注释的需求图像注解的类型分类法物体检测语义分割用OpenCV实现图像注解包围盒方法KNN方法进行分割结论参考文献图像标注在计算机视觉中很重要,计算机视觉是一种技...
    99+
    2024-04-02
  • PaddlePaddle中有哪些常用的图像增强技术
    PaddlePaddle中常用的图像增强技术包括: 随机裁剪(RandomCrop):在训练图像中随机裁剪出指定大小的区域,可以...
    99+
    2024-04-02
  • PHP图像处理函数精讲:imagecreatefromjpeg、imagecopyresized、imagepng等函数的图像处理技术
    PHP图像处理函数精讲:imagecreatefromjpeg、imagecopyresized、imagepng等函数的图像处理技术图像处理在现代网络应用中扮演着重要的角色,无论是上传用户头像、生成缩略图还是应用程序中的图形处理,都离不开...
    99+
    2023-11-18
    PHP图像处理函数关键词:
  • Java绘图技术基础(实例讲解)
    如下所示:public class Demo1 extends JFrame{ MyPanel mp=null; public static void main(String[] args){ Demo1 demo=new D...
    99+
    2023-05-31
    java 绘图技术 ava
  • Java绘图技术的详解及实例
    Java绘图技术的详解及实例简单实例public class Demo1 extends JFrame{ MyPanel mp=null; public static void main(String[] args){ Dem...
    99+
    2023-05-31
    java 绘图 ava
  • PHP 图片处理的革命:掌握现代图像操作技术
    随着数字图像在现代生活中的普遍存在,图像操作技术变得至关重要。PHP作为一种流行的服务器端编程语言,在图像处理领域扮演着重要角色。本文将探讨PHP图片处理的最新发展,帮助开发者掌握现代图像操作技术。 ImageMagick和GD库:传统图...
    99+
    2024-04-02
  • Python底层技术揭秘:如何实现图像处理
    Python底层技术揭秘:图像处理的实现及代码示例导语:图像处理是计算机科学中十分重要的一个领域。通过使用Python以及相关的底层技术,我们能够实现各种各样的图像处理操作。在本文中,我们将揭示Python图像处理的底层技术,并提供一些实用...
    99+
    2023-11-08
    Python 技术 图像处理
  • 亚马逊镜像review技术
    具体而言,镜像Review技术可以通过以下步骤实现: 将特定的评论从一台计算机上复制到另一台计算机上。这通常涉及使用云存储服务来将评论上传到云端。 使用一些软件工具来扫描镜像,以确保评论是由用户生成的,并且没有被恶意攻击者利用。 将镜像...
    99+
    2023-10-27
    亚马逊 镜像 技术
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作