成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Java圖像技術(shù)(轉(zhuǎn))

筆者在這里將畫(huà)線,畫(huà)或填充多邊形等理解為"圖形"技術(shù),將圖片的變換,顯示理解為"圖像"技術(shù).

相對(duì)而言,圖形技術(shù)較簡(jiǎn)單,圖像技術(shù)較復(fù)雜.下面筆者從實(shí)用的角度出發(fā),講解幾個(gè)圖像編程問(wèn)題.首先,我們看下面這個(gè)程序.

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



程序非常簡(jiǎn)單. 但你注意到?jīng)]有,在瀏覽器的狀態(tài)欄,顯示出的數(shù)值并不一定是1: 你要顯示的圖片幅面越大,這個(gè)數(shù)值越大.這說(shuō)明 paint() 方法被調(diào)用了不止一次.那么,是誰(shuí),在什么時(shí)候調(diào)用的?

事實(shí)上,每當(dāng)有新的圖片數(shù)據(jù)到達(dá)或生成時(shí),Java小程序都會(huì)自動(dòng)去調(diào)用paint()方法重繪屏幕.這個(gè)工作由ImageObserver接口的imageUpdate()方法實(shí)現(xiàn).你可以超越這個(gè)imageUpdate()方法,自己重新編程.考慮到本地的機(jī)器從Web服務(wù)器上獲取圖片的速度一般比較慢,很多時(shí)候你必須要知道已經(jīng)有多少圖片數(shù)據(jù)已經(jīng)被下載.下面給出一個(gè)示范程序,程序可以一邊下載,一邊顯示,同時(shí)通知用戶已經(jīng)獲得多少圖片數(shù)據(jù).

import java.awt.*;

import java.applet.*;

import java.awt.image.*;

public class image_download extends Applet

{

Image img;

int step=0;//step 用來(lái)表述已被下載的那部分圖片的高度

int percent=0;//percent 用來(lái)表述已下載的圖片的高度占圖片總高度的百分比

public void init()

{

img=getImage(getCodeBase(),"mama.gif");

}

public void paint(Graphics g)

{

g.drawImage(img,0,0,this);

}

 

//下面我們超越本來(lái)的imageUpdate()方法.每當(dāng)有新的圖片數(shù)據(jù)到達(dá)(或產(chǎn)生)時(shí)此方法會(huì)被自動(dòng)調(diào)用

public boolean imageUpdate(Image img_ob,int flags,int x,int y,int width,int height)

{

if(((flags & SOMEBITS)!=0) & (img_ob==img))//判斷是否又有新的圖像數(shù)據(jù)都被下載

{

step=step+height;//計(jì)算已被下載的圖片的高度

percent=step*100/img.getHeight(this);//計(jì)算這個(gè)高度占圖片高度的的百分比

showStatus(percent+"%");//在狀態(tài)欄顯示

repaint(x,y,width,height);//重繪屏幕.但只畫(huà)新數(shù)據(jù)表達(dá)的部分.簡(jiǎn)單使用repaint()重繪

//整個(gè)屏幕會(huì)使畫(huà)面閃爍

}

if((flags & ERROR)!=0)//假如下載出錯(cuò)

showStatus("image loading error");

if((flags & ALLBITS)!=0)//假如全部圖片數(shù)據(jù)都已下載完

showStatus("Done");

return true;

}

}

HTML文件如下:



imageUpdate()參數(shù)說(shuō)明如下:

img_ob: 被監(jiān)視的圖像.

flags: 被監(jiān)視圖像的狀態(tài).

ABORT: 圖像生成被異常中斷

ALLBITS: 全部圖像都已生成

ERROR: 發(fā)生錯(cuò)誤

FRAMEBITS: 完成一幅

HEIGHT: 本次生成的高度

SOMEBITS: 已將生成了一部分圖像

WIDTH: 本次生成的寬度

x: x軸坐標(biāo)

y: y軸坐標(biāo)

width: 本次下載的圖像的寬度

height: 本次下載的圖像的高度

 

下面用兩個(gè)例子說(shuō)明怎樣獲取大幅圖像的局部.第一個(gè)例子使用CropImageFilter類去獲得圖像的局部.你可以這樣使用這種技術(shù):

首先根據(jù)圖像裁剪過(guò)濾器產(chǎn)生圖像過(guò)濾器.

ImageFilter filter=new CropImageFilter (int x, int y, int width, int height).

x: 裁剪起始點(diǎn) X 軸坐標(biāo)

y: 裁剪起始點(diǎn)Y 軸坐標(biāo)

width: 裁剪寬度

height: 裁剪高度

然后根據(jù)根據(jù)過(guò)濾器產(chǎn)生圖像生產(chǎn)者. ImageProducer procuder=new FilteredImageSource(baseImage.getSource(),filter).

baseImage: 將要被裁剪的圖片

然后根據(jù)圖像生產(chǎn)者產(chǎn)生新的圖像. Image img=createImage(procuder).

下面的程序使用上述技術(shù)裁剪圖片.程序運(yùn)行后,你用"拖拽"鼠標(biāo)的方式(按住鼠標(biāo)鍵并移動(dòng)鼠標(biāo))在圖片上選定一片區(qū)域,然后再在運(yùn)行區(qū)上點(diǎn)擊鼠標(biāo),剛才你選定的區(qū)域的圖片將被復(fù)制到這個(gè)位置.要注意的是,程序并未對(duì)選擇區(qū)域的起始點(diǎn)和終止點(diǎn)的相對(duì)位置作出判斷,因此,你一定要使終止點(diǎn)在起始點(diǎn)的右下方.

import java.awt.*;

import java.applet.*;

import java.awt.image.*;

public class CropFilterImage extends Applet

{

Image baseImage,cropImage;//baseImage是原始圖片,cropImage是根據(jù)選定區(qū)域產(chǎn)生的新圖片

int sx,sy;//選定區(qū)域起始點(diǎn)坐標(biāo)

int dx=0,dy=0;//要顯示新圖片的位置

int width,height;//選定區(qū)域的寬和高

boolean selected=false;//用來(lái)判定現(xiàn)在用戶在干什么

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)//假如用戶開(kāi)始選擇

{

sx=x;//記下起始點(diǎn)

sy=y;

selected=true;

return true;

}

else//假如用戶已經(jīng)設(shè)定了選擇區(qū)

{

dx=x;

dy=y;

cropImage=cropImage();//裁剪圖像

repaint();//重畫(huà)屏幕

selected=false;

}

return true;

}

public boolean mouseUp(Event evt,int x,int y)

{

if(selected)//用戶松開(kāi)鼠標(biāo)健表示已確定選擇區(qū)

{

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);//根據(jù)圖像裁剪過(guò)濾器產(chǎn)生過(guò)濾器

//下面根據(jù)過(guò)濾器產(chǎn)生圖像生產(chǎn)者

ImageProducer producer=new FilteredImageSource(baseImage.getSource(),filter);

Image img=createImage(producer);//根據(jù)圖像生產(chǎn)者產(chǎn)生新圖像

return img;

}

}

HTML文件如下:



 

很多情況下上面的方法不實(shí)用.比如你想對(duì)圖片作出某種變換,上面的方法就無(wú)能為力了.下面的程序給出更強(qiáng)大的算法:將圖像數(shù)據(jù)取到數(shù)組中,再在數(shù)組中將需要的數(shù)據(jù)提取出來(lái),依據(jù)這些數(shù)據(jù)再生成新的圖像去顯示.設(shè)想你有一個(gè)幅面大于窗口尺寸的圖像要顯示,你必須要讓用戶可以控制窗口的位置,通過(guò)移動(dòng)窗口,瀏覽

整個(gè)圖像.程序運(yùn)行后,你可以用四個(gè)光標(biāo)鍵移動(dòng)窗口瀏覽全部圖像.

程序中的關(guān)鍵技術(shù)有三個(gè),第一個(gè)是PixelGrabber類用于獲取圖像數(shù)據(jù).你可以這樣使用:

首先生成一個(gè)PixelGrabber實(shí)例:

PixelGrabber pg=new PixelGrabber(Image img,int x,int y,int width,int height,int pix[ ],int offset,int scansize)

img: 被取數(shù)據(jù)的圖像

x: 起始點(diǎn) x 軸坐標(biāo)

y: 起始點(diǎn) y 軸坐標(biāo)

width: 圖像寬度

height: 圖像高度

pix[ ]: 目標(biāo)數(shù)組

offset: 目標(biāo)數(shù)組的起始地址

scansize: 圖像每行點(diǎn)數(shù)

然后使用grabPixels( ) 方法取數(shù)據(jù):

try { pg.grabPixels( ) ; }

catch ( InterruptedException e) { }

第二個(gè)關(guān)鍵技術(shù)是使用媒體追蹤器MediaTracker監(jiān)視圖像的生成情況.你可以這樣使用:

首先生成一個(gè)媒體追蹤器的實(shí)例:

MediaTracker mt=new MediaTracker(this);

 

然后向其中加入要追蹤的圖像:

mt.addImage(Image image,int ID)

image是你要追蹤的圖像, ID是你設(shè)定的一個(gè)表示這個(gè)圖像的序號(hào).

然后使用waitForID ( int ID ) 或 waitForAll( ) 等待圖像全部生成

try { mt.waitForID(1);}

catch(InterruptedException e){ }

第三個(gè)關(guān)鍵技術(shù)是使用內(nèi)存數(shù)據(jù)(數(shù)組)產(chǎn)生圖像.你可以這樣使用:

createImage(new MemoryImageSource(int width, int height, int pix[ ], int offset, int scanwidth)

width: 欲生成的圖像的寬度

heidth: 欲生成的圖像的高度

pix[ ]: 數(shù)據(jù)源

offset: 叢數(shù)組的哪里開(kāi)始使用數(shù)據(jù)

scanwidth: 圖像每行的象素?cái)?shù)

程序如下:

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;//窗口的左上角坐標(biāo)

int point_img_full,point_img_window;//原始圖像數(shù)據(jù)數(shù)組的操作地址和窗口圖像數(shù)據(jù)數(shù)組的操作地址

int img_full_data[];//原始圖像數(shù)據(jù)數(shù)組.沒(méi)有初始化是因?yàn)楝F(xiàn)在不知道原始圖像的大小

int img_window_data[]=new int[window_width * window_height];//窗口圖像數(shù)據(jù)數(shù)組

MediaTracker mt=new MediaTracker(this);//媒體追蹤器

PixelGrabber img_full_grabber;//用來(lái)獲取原始圖像的數(shù)據(jù)

public void init()

{

img_window=createImage(window_width,window_height);//創(chuàng)建窗口圖像

img_full=getImage(getCodeBase(),"mama.gif");

//下面要等待直到全部的原始圖像數(shù)據(jù)都被正確載入.否則無(wú)法知道原始圖像的大小

mt.addImage(img_full,1);//向媒體追蹤其中加入要追蹤的圖像

try{mt.waitForID(1);} // 等待全部數(shù)據(jù)被正確載入

catch(InterruptedException e){ }

img_width=img_full.getWidth(this);//現(xiàn)在可以獲取原始圖像的正確信息了.取它的寬和高

img_height=img_full.getHeight(this);

img_full_data=new int[img_width * img_height];//初始化原始圖像數(shù)據(jù)數(shù)組

img_full_grabber=new PixelGrabber(img_full,0,0,img_width,img_height,img_full_data,0,img_width);//準(zhǔn)備獲取圖像數(shù)據(jù)

try{img_full_grabber.grabPixels();}//采集數(shù)據(jù)

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;//從這個(gè)位置開(kāi)始獲取原始圖像數(shù)據(jù)

point_img_window=0;//從這個(gè)位置開(kāi)始向窗口圖像數(shù)據(jù)數(shù)組放數(shù)據(jù)

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;//開(kāi)始處理下一行

}

img_window=createImage(new MemoryImageSource(window_width,window_height,img_window_data,0,window_width));//根據(jù)內(nèi)存數(shù)據(jù)(數(shù)組)生成圖像

//等待圖像完全生成.否則一邊生成一邊繪制窗口圖像會(huì)閃爍.

mt.addImage(img_window,1);

try{mt.waitForID(1);}

catch(InterruptedException e){}

}

//下面的鍵盤事件方法根據(jù)用戶的按鍵重置窗口坐標(biāo),再生成圖像,再顯示

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



 

下面的程序?qū)蓚€(gè)圖像進(jìn)行合成并顯示來(lái)模擬圖像的淡入淡出.程序運(yùn)行后,每按一次向上鍵,前景圖像就增強(qiáng)一點(diǎn),每按一次向下鍵,前景圖像就減弱一點(diǎn).

首先你要了解圖像數(shù)據(jù).

每個(gè)象素點(diǎn)的信息由一個(gè)整數(shù)表達(dá).整數(shù)共32個(gè)二進(jìn)制位,從左向右,分成四個(gè)部分,每部分都是8位.

第一部分: Alpha 信息.控制圖像顯示的強(qiáng)度.下面的程序就是通過(guò)調(diào)整這個(gè)數(shù)值控制圖像的淡入淡出.

第二部分:紅色數(shù)據(jù).

第三部分:綠色數(shù)據(jù).

第四部分:藍(lán)色數(shù)據(jù).

程序使用的方法是:先畫(huà)背景圖像,再在上面畫(huà)帶Alpha數(shù)據(jù)的前景圖像,通過(guò)調(diào)整Alpha值使前景圖像淡入 淡出.

import java.applet.*;

import java.awt.*;

import java.awt.image.*;

public class alpha extends Applet

{

Image background, foreground;//背景圖像和前景圖像

Image foreground_new;//依據(jù)前景圖像生成的帶Alpha通道的新圖像

MediaTracker mt;

int foreground_alpha=175;//前景圖像的起始Alpha值

int foreground_data[];//用來(lái)生成新圖像的內(nèi)存數(shù)據(jù)

PixelGrabber pg;

int transparancy;//前景圖像的全透明點(diǎn)的像素值.只要前景圖像的某個(gè)點(diǎn)是這個(gè)值,它就全透明

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();} // 等待所有圖片的數(shù)據(jù)都被正確載入

catch(InterruptedException e){ }

foreground_data=new int[foreground.getWidth(this) * foreground.getHeight(this)];//初始化

//下面把前景圖片的數(shù)據(jù)載入數(shù)組

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

//下面我把圖像左上角的點(diǎn)的值作為透明值.假如圖像中哪個(gè)點(diǎn)的值和左上角的點(diǎn)的值一樣,

//這個(gè)點(diǎn)就全透明--背景100%出現(xiàn).我用這個(gè)比較簡(jiǎn)單的辦法把前景圖像中我不想要的部分去掉

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)//依據(jù)按鍵改變Alpha值

foreground_alpha++;

if (key==Event.DOWN && foreground_alpha>0)

foreground_alpha--;

showStatus(String.valueOf(foreground_alpha));//在狀態(tài)欄顯示Alpha值

for (int i=0;i<(foreground.getWidth(this) * foreground.getHeight(this));i++)//逐點(diǎn)處理

{

foreground_data[i]=foreground_data[i] & 0x00ffffff;//置此點(diǎn)為全透明

if (foreground_data[i]!=transparancy)//假如這個(gè)點(diǎn)的值和全透明點(diǎn)不同

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);//先畫(huà)背景

getGraphics().drawImage(foreground_new,100,100,this);//再畫(huà)前景

return true;

}

}

下面是HTML文件:


 [@more@]

當(dāng)前名稱:Java圖像技術(shù)(轉(zhuǎn))
文章出自:http://jinyejixie.com/article2/iiccoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、面包屑導(dǎo)航網(wǎng)站收錄、軟件開(kāi)發(fā)、小程序開(kāi)發(fā)、網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
河池市| 航空| 广西| 金门县| 通渭县| 丰顺县| 延川县| 庐江县| 湘乡市| 民权县| 广州市| 剑阁县| 垫江县| 福安市| 平定县| 沙田区| 彭州市| 东莞市| 蒙城县| 凤翔县| 富顺县| 潜山县| 晴隆县| 定远县| 桂平市| 和龙市| 镇安县| 昔阳县| 阜南县| 谷城县| 荥经县| 丰台区| 黄浦区| 濮阳市| 大邑县| 中方县| 贵港市| 韶山市| 龙游县| 肃宁县| 崇信县|