多媒體編程知識_第1頁
多媒體編程知識_第2頁
多媒體編程知識_第3頁
多媒體編程知識_第4頁
多媒體編程知識_第5頁
已閱讀5頁,還剩62頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

多媒體編程知識11.1圖像處理Java支持兩種圖像格式JPEG和GIF。11.1.1圖像種類1.BMPBMP是Windows的標準位圖文件格式,含有固定數(shù)量的像素點顏色,可用Windows的畫圖程序打開。這種圖像在放大時,會出現(xiàn)鋸齒邊緣,變得很不清晰。圖像文件沒有被壓縮過,規(guī)模較大,不適合在InternetJava不能顯示這種圖像。2.JPEG或JPGJPEG稱為聯(lián)合圖像專家組(jointphotographicexpertsgroup),可用瀏覽器打開。JPEG(或JPG)圖像格式一般用來顯示照片和具有連續(xù)色調(diào)的圖像,它能保存圖像所有顏色信息。JPEG是一種壓縮的文件格式,在打開時自動解壓縮。由于壓縮后的文件規(guī)模較小,成為Internet上廣泛使用的圖像格式,Java可以顯示這種圖像。3.GIFGIF稱為圖像交換格式(graphicinterchangeformat),可用瀏覽器打開。GIF圖像是一種壓縮文件格式,由于它能最大限度地減少文件轉換時間,所以在HTML文件中常用于顯示插圖或圖標。GIF格式能有效減少文件大小,有利于在Internet上使用,Java支持這種圖像格式。圖11.111.1.2圖像的顯示例11.1在Applet中顯示一幅圖像,如圖11.1所示。importjava.applet.Applet;importjava.awt.Image;importjava.awt.Graphics;publicclassShowImageextendsApplet{Imageimg;publicvoidinit(){img=getImage(getCodeBase(),″bld.jpg″);}publicvoidpaint(Graphicsg){g.drawImage(img,30,10,this);}}1.加載圖像加載圖像一般放在初始化方法init中進行。程序中的getImage方法可加載Java支持的圖像文件,它有兩個參數(shù),一個是圖像文件地址,一個是圖像文件名稱。由于Applet是面向網(wǎng)絡的,因此圖像文件的存儲位置并不局限于本地計算機的磁盤目錄,大部分情況是直接讀取Web服務器上的圖像文件。getImage方法返回一個Image對象,它的調(diào)用格式為:ImagegetImage(URLurl)ImagegetImage(URLurl,Stringname)其中url是一個URL類的對象,代表一個網(wǎng)絡地址(關于URL的概念請參考下一章的內(nèi)容),例如下面的語句可以加載sun公司W(wǎng)eb服務器指定位置上的一幅圖片:getImage(newURL(″://java.sun/graphics/people.gif″));2.顯示圖像顯示圖像需要調(diào)用Graphics類的方法drawImage,它可以將Image對象關聯(lián)的圖像顯示在Applet的指定位置。drawImage方法的調(diào)用格式如下:booleandrawImage(Imageimg,intx,inty,ImageObserverobserver)booleandrawImage(Imageimg,intx,inty,Colorbgcolor,ImageObserverobserver)其中img就是要顯示的圖像、x和y是圖像顯示位置(x和y可取負值,表示一部分圖像被移出了顯示區(qū))、bgcolor是圖像顯示區(qū)域的背景色、observer是圖像加載跟蹤器,通常將該參數(shù)指定為this,即由Applet負責跟蹤圖像的加載情況。這兩種方法都是將圖像照原樣顯示,能不能對圖像進行縮放呢?使用下面兩種調(diào)用格式就可以對圖像進行縮放顯示:booleandrawImage(Imageimg,intx,inty,intwidth,intheight,ImageObserverobserver)booleandrawImage(Imageimg,intx,inty,intw,inth,Colorc,ImageObserverobserver)圖11.2例11.2圖像的縮放顯示,如圖11.2所示。importjava.awt.*;importjava.applet.*;publicclassShowImage1extendsApplet{Imageimg;publicvoidinit(){img=getImage(getCodeBase(),″ball.jpg″);}publicvoidpaint(Graphicsg){intw=img.getWidth(this);inth=img.getHeight(this);g.drawImage(img,20,40,this);//原圖g.drawImage(img,120,70,w/2,h/2,this);//縮小一倍g.drawImage(img,160,0,w*2,h*2,this);//放大一倍}}上述程序加載了一個圓球圖像,在paint方法中調(diào)用getWidth和getHeight方法取得圖像的寬度和高度。然后分別顯示了原圖、縮小一倍和放大一倍的圖像。11.1.3幻燈機效果如果Applet僅僅是顯示一幅圖像,沒有什么特別的意義,不如直接在HTML文件中顯示圖像。Applet應該做HTML做不到的事情,例如像幻燈機那樣連續(xù)顯示圖像。例11.3多幅圖像的顯示,如圖11.3所示。圖11.3importjava.awt.*;importjava.awt.event.*;importjava.applet.*;publicclassShowImage2extendsApplet{intindex;Imageimgs[]=newImage[6];publicvoidinit(){addMouseListener(newMouseAdapter(){publicvoidmouseClicked(MouseEvente){index=++index%6;repaint();}});for(inti=0;i<6;i++)imgs[i]=getImage(getCodeBase(),″duke″+(i+1)+″.gif″);}publicvoidpaint(Graphicsg){if(imgs[index]!=null)g.drawImage(imgs[index],60,20,this);}publicvoidpaint(Graphicsg){if(imgs[index]!=null)g.drawImage(imgs[index],60,20,this);}}11.1.4生成圖像Java有一個圖像生成器MemoryImageSource類,可用它在內(nèi)存中生成一幅圖像。下面的例子可在Applet上顯示了一個漸變底色。圖11.4例11.4一個漸變圖像的生成,如圖11.4所示。importjava.awt.*;importjava.awt.image.*;importjava.applet.*;publicclassshowextendsApplet{Imageimg;publicvoidinit(){intw=256;//圖像的寬度設為256inth=256;//圖像的高度設為256int[]pix=newint[w*h];intindex=0;for(intred=0;red<h;red++)//red從0變到255for(intblue=0;blue<w;blue++)//blue從0變到255pix[index++]=(255<<24)|(red<<16)|blue;img=createImage(newMemoryImageSource(w,h,pix,0,w));}publicvoidpaint(Graphicsg){g.drawImage(img,0,0,this);}}createImage方法可以創(chuàng)建一個圖像對象,它的參數(shù)是一個圖像生成器,這個圖像生成器由MemoryImageSource方法擔任。該方法有5個參數(shù):圖像的寬度和高度、代表圖像每一點顏色值的數(shù)組、畫圖像時的起始位置、掃描線的寬度。在init方法中,將這5個參數(shù)準備好后,生成了圖像對象,最后在paint方法中將這個圖像顯示出來。11.1.5圖形旋轉與透明處理在JavaAWT中有一個增強圖形類Graphics2D,提供了對圖形、圖像和文本的特殊處理,可實現(xiàn)縮放、旋轉、透明等效果。下面的例子演示了圖形的旋轉與透明處理。圖11.5例11.5圖形的旋轉與透明處理,如圖11.5所示。importjava.awt.Color;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.AlphaComposite;publicclassRotateextendsjava.applet.Applet{publicvoidpaint(Graphicsg){g.setColor(Color.red);g.fillRect(100,30,100,100);Graphics2Dg2=(Graphics2D)g;//將g強制轉換為Graphics2D類型intrule=AlphaComposite.SRC-OVER;//指定顏色合成模式floatalpha=0.5f;//指定顏色透明值AlphaCompositeac=AlphaComposite.getInstance(rule,alpha);g2.setComposite(ac);//設定g2的顏色合成模式g2.setColor(Color.blue);g2.translate(150,10);//轉換g2的坐標系,平移到(150,10)g2.rotate((45*Math.PI)/180);//繪圖區(qū)順時針旋轉45度g2.fillRect(0,0,100,100);}}根據(jù)這兩個參數(shù)值,調(diào)用AlphaComposite的getInstance方法創(chuàng)建模式對象ac,然后根據(jù)ac調(diào)用Graphics2D的setComposite方法設定繪圖區(qū)的顏色合成模式,此后將按照新模式畫出圖形。Graphics2D的rotate方法以弧度為單位將繪圖區(qū)順時針旋轉一個指定角度,由于旋轉后坐標系發(fā)生變化,所以要先調(diào)用translate方法把坐標系平移,使畫出的圖形保持在原坐標系的位置上。11.2動畫處理戲軟件的設計中,動畫向程序員提出了挑戰(zhàn),但在Java中實現(xiàn)動畫則是十分簡單的事情。下面讓我們一起由淺入深地編寫幾個動畫程序實例,并通過對這些實例的逐步改進來探討Java動畫技術的關鍵。11.2.1動畫原理其實,計算機動畫原理十分簡單,首先在屏幕上顯示出第一幀畫面,過一會兒把它擦掉,然后再顯示下一幀畫面,如此循環(huán)往復。由于人眼存在著一個視覺差,所以感覺好像畫面中的物體在不斷運動。圖11.6例11.6宇宙飛船游太空,如圖11.6所示。importjava.awt.*;importjava.applet.*;publicclassMovingImgextendsApplet{Imagestar,rocket;intx=10;publicvoidinit(){star=getImage(getCodeBase(),″starfield.gif″);rocket=getImage(getCodeBase(),″rocket.gif″);}publicvoidpaint(Graphicsg){g.drawImage(star,0,0,this);g.drawImage(rocket,x,15,this);try{Thread.sleep(50);x+=5;if(x==210){x=10;Thread.sleep(1000);}}catch(InterruptedExceptione){}repaint();}}這是一個很簡單的動畫,在Applet中有一個充當太空的背景圖,一艘宇宙飛船在太空圖上不斷從左邊移動到右邊。程序中創(chuàng)建了兩個Image對象star和rocket,在init方法中分別加載了兩個圖像文件和這兩個對象關聯(lián)起來。添加了變量x用來指定飛船的畫出位置,x初始化為10。在paint方法中,注意到太空總是畫在指定位置(0,0),而飛船則畫在位置(x,15),其中x的值是不斷變化的。真正使飛船實現(xiàn)動畫效果是在try...catch塊中。paint方法的最后一條語句是調(diào)用repaint方法。repaint方法的功能是重畫圖像,它先調(diào)用update方法將顯示區(qū)清空,再調(diào)用paint方法畫出圖像。這就形成了一個循環(huán),paint調(diào)用了repaint,而repaint又調(diào)用了paint,使飛船不間斷地來回移動。運行這個Applet時,畫面有閃爍現(xiàn)象。一般來說,畫面越大,update以背景色清除顯示區(qū)所占用的時間就越長,不可避免地會產(chǎn)生閃爍。為了達到平滑而又沒有閃爍的動畫效果,就應該考慮采取一些補救措施。覆蓋update方法可以降低閃爍,但不能消除它。能有效消除閃爍的方法是采用圖形雙緩沖技術(graphicsdoublebuffering)。圖11.711.2.2圖形雙緩沖例11.7改進后的宇宙飛船游太空,參見圖11.6importjava.awt.*;importjava.applet.*;publicclassMovingImg1extendsApplet{Imagestar,rocket,buffer;GraphicsgContext;intx=10;publicvoidinit(){star=getImage(getCodeBase(),″starfield.gif″);rocket=getImage(getCodeBase(),″rocket.gif″);buffer=createImage(getWidth(),getHeight());gContext=buffer.getGraphics();}publicvoidpaint(Graphicsg){gContext.drawImage(star,0,0,this);gContext.drawImage(rocket,x,15,this);g.drawImage(buffer,0,0,this);try{Thread.sleep(10);x+=2;if(x==210){x=10;Thread.sleep(1000);}catch(InterruptedExceptione){}repaint();}publicvoidupdate(Graphicsg){paint(g);}}11.2.3用線程實現(xiàn)動畫例11.7用圖形雙緩沖改善了圖像閃爍問題,但仍存在一些其他問題。例如用戶離開網(wǎng)頁后,嵌入的Applet會繼續(xù)運行,占用CPU時間。下面的例子出于網(wǎng)絡實用的目的,采用獨立線程實現(xiàn)動畫。importjava.awt.*;importjava.applet.*;publicclassRunningextendsAppletimplementsRunnable{Imageimg[]=newImage[10];Imagebuffer;GraphicsgContext;Threadanimate;intindex=0;publicvoidinit(){buffer=createImage(getWidth(),getHeight());gContext=buffer.getGraphics();for(inti=0;i<10;i++)img[i]=getImage(getCodeBase(),″T″+(i+1)+″.gif″);}publicvoidstart(){if(animate==null){animate=newThread(this);animate.start();}}publicvoidstop(){if(animate!=null)animate=null;}publicvoidrun(){while(true){gContext.drawImage(img[index],100,20,this);repaint();try{animate.sleep(50);}catch(InterruptedExceptione){}gContext.clearRect(100,20,100,100);index=++index%10;}}publicvoidpaint(Graphicsg){g.drawImage(buffer,0,0,this);}publicvoidupdate(Graphicsg){paint(g);}}本程序加載了10個圖像(T1.gif~T10.gif),采用了圖形雙緩沖技術,實現(xiàn)了Runnable接口中的run方法,這是一個和Applet同時運行的線程。對線程的控制由Applet的start和stop方法完成,Applet運行時,就在start方法中啟動線程,Applet停止時,就在stop方法中停止線程。對圖像的操作全部放在run方法的永恒循環(huán)當中。首先調(diào)用gContext的drawImage方法把當前圖像畫在屏幕緩沖區(qū)內(nèi),怎樣把它顯示在屏幕上呢?是在paint方法中把屏幕緩沖區(qū)拷貝到屏幕上。但paint方法一般無法直接調(diào)用,因為要傳遞給它一個圖形參數(shù),所以通過調(diào)用repaint方法來間接調(diào)用paint以完成屏幕拷貝。repaint方法無參數(shù),它將調(diào)用update方法,由update方法調(diào)用paint方法并傳遞g參數(shù)。這就是我們曾介紹過的一個線程負責準備圖像而另一個線程負責顯示圖像的動畫方法。接下來,線程休眠50毫秒,然后清除屏幕緩沖區(qū)中的圖像,將圖像下標加1并取模。如果不清除屏幕緩沖區(qū)中的圖像,將會出現(xiàn)圖像重疊。下標加1后求余數(shù),可保證取值范圍總是0~9。11.2.4文字的動畫顯示例11.9顯示一個由小連續(xù)變大的字符串,如圖11.8所示。圖11.8importjava.awt.*;importjava.applet.*;publicclassRollingextendsAppletimplementsRunnable{Imagebuffer;GraphicsgContext;Threadanimate;Strings=″這是文字動畫″;intw,h,x,y,size=12;publicvoidinit(){w=getWidth();h=getHeight();buffer=createImage(w,h);gContext=buffer.getGraphics();gContext.setColor(Color.blue);}publicvoidstart(){if(animate==null){animate=newThread(this);animate.start();}}publicvoidstop(){if(animate!=null)animate=null;}publicvoidrun(){while(true){x=(w-s.length()*size)/2;y=(h+size)/2;gContext.setFont(newFont(″宋體″,Font.PLAIN,size));gContext.drawString(s,x,y);repaint();try{animate.sleep(50);}catch(InterruptedExceptione){}gContext.clearRect(0,0,w,h);if(++size>40)size=12;}}publicvoidpaint(Graphicsg){g.drawImage(buffer,0,0,this);}publicvoidupdate(Graphicsg){paint(g);}}在run方法的永恒循環(huán)中,首先計算出字符串顯示位置x和y,使字符串每一次都顯示在Applet的中心。調(diào)用gContext的setFont方法指定字體為宋體、字體風格為PLAIN、字體大小為size。調(diào)用gContext的drawString方法在指定位置輸出字符串。然后調(diào)用repaint方法進行屏幕拷貝。線程休眠50毫秒后,清除后臺屏幕中的圖像。最后,對字體大小size進行處理,每次增量后,如果size大于40就恢復到初始值12。11.2.5圖像高級處理——水中倒影例11.10用一幅圖像制作出它的水中倒影,并能顯示水波紋,如圖11.9所示。圖11.9importjava.awt.*;importjava.applet.*;publicclassLakeextendsAppletimplementsRunnable{Threadanimate;Imageimg,buffer;GraphicsgContext;intwidth,height;publicvoidinit(){img=getImage(getCodeBase(),″tree.jpeg″);MediaTrackertracker=newMediaTracker(this);//創(chuàng)建圖像加載跟蹤器tracker.addImage(img,0);//添加要跟蹤的圖像,代號為0try{tracker.waitForID(0);//等待圖像加載完畢}catch(InterruptedExceptione){}width=img.getWidth(this);height=img.getHeight(this)/2;//僅使用圖像的一半buffer=createImage(2*width,height);//創(chuàng)建后臺屏幕,原始圖像的兩倍寬度gContext=buffer.getGraphics();gContext.drawImage(img,0,-height,this);//圖像的下半部分畫到后臺屏幕for(inti=0;i<height;i++)//將圖像逐線拷貝,生成圖像倒影gContext.copyArea(0,i,width,1,width,(height-1)-2*i);//拷貝到后臺屏幕右半邊gContext.clearRect(0,0,width,height);//清除后臺屏幕左半邊}publicvoidstart(){if(animate==null){animate=newThread(this);animate.start();}}publicvoidstop(){if(animate!=null)animate=null;}publicvoidrun(){intdy,num=0;doubled;while(true){d=num*Math.PI/6;//生成一個角度,共有12個值for(inti=0;i<height;i++){dy=(int)((i/12.0D+1)*Math.sin(height/12.0D*(height-i)/(i+1)+d));//經(jīng)驗公式gContext.copyArea(width,i+dy,width,1,-width,-dy);//從右向左拷貝生成波紋}repaint();num=++num%12;try{Thread.sleep(50);}catch(InterruptedExceptione){}}}publicvoidupdate(Graphicsg){paint(g);}publicvoidpaint(Graphicsg){g.drawImage(img,0,-height,this);//顯示圖像的下半部分g.drawImage(buffer,0,height,this);//顯示圖像倒影,合成一幅完整圖像}}11.3數(shù)字音頻11.3.1加載聲音文件在Applet中播放聲音十分簡單,加載聲音文件,然后調(diào)用play方法播放即可。Java提供了兩種播放聲音的方式:一種是通過Applet類的play方法,一種是通過AudioClip接口中的方法來播放。Applet的play方法可以將聲音文件的加載與播放一并完成,其調(diào)用格式如下:voidplay(URLurl)voidplay(URLurl,Stringname)其中URL是一個網(wǎng)絡地址,網(wǎng)絡地址若包含聲音文件可采用第一種形式,否則采用第二種形式,播放本地計算機上的聲音文件也可采用第二種形式。假設有一個MIDI聲音文件trip.mid和Applet放在同一個目錄下,采用如下調(diào)用格式即可播放:play(getCodeBase(),″trip.mid″);Applet的getAudioClip方法可創(chuàng)建這樣的對象,該方法加載指定網(wǎng)絡地址的聲音文件,并返回一個AudioClip對象,調(diào)用格式如下:AudioClipgetAudioClip(URLurl)AudioClipgetAudioClip(URLurl,Stringname)創(chuàng)建AudioClip對象后,聲音文件即被加載,可調(diào)用它的方法處理聲音文件。如果該方法沒有找到指定的聲音文件,將返回null值,此時不能引用所創(chuàng)建的對象。AudioClip只有3個方法:voidplay()播放一遍;voidloop()連續(xù)播放;voidstop()停止播放。11.3.2在Applet中播放聲音例11.11本地計算機工作目錄下有5個聲音文件,代表了5種聲音格式,加載并播放這些聲音文件。結果如圖11.10所示。圖11.10importjava.awt.*;importjava.awt.event.*;importjava.applet.Applet;importjava.applet.AudioClip;publicclassSoundPlayextendsAppletimplement

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論