濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > Java應(yīng)用程序中創(chuàng)建圖像

Java應(yīng)用程序中創(chuàng)建圖像

熱門標(biāo)簽:黃石智能營(yíng)銷電銷機(jī)器人效果 電話機(jī)器人的特色和創(chuàng)新 地圖標(biāo)注人員兼職 漯河辦理400電話 淮南騰訊地圖標(biāo)注 怎樣把地圖標(biāo)注出來 商丘百應(yīng)電話機(jī)器人有沒有效果 騰訊地圖標(biāo)注商戶改名注冊(cè)入駐 開封便宜外呼系統(tǒng)報(bào)價(jià)
合成圖像

  您不必從文件中讀取所有的圖像 — 您可以創(chuàng)建自己的圖像。要?jiǎng)?chuàng)建自己的圖像,最靈活的方法是用一個(gè) BufferedImage 對(duì)象,它是 Image 類的一個(gè)子類,它把圖像數(shù)據(jù)存儲(chǔ)在一個(gè)可以被訪問的緩沖區(qū)中。它還支持各種存儲(chǔ)像素?cái)?shù)據(jù)的方法:使用或不使用 alpha 通道、不同種類的顏色模型以及顏色組件的各種精確度。ColorModel 類提供一種靈活的方法定義各種顏色模型,以和 BufferedImage 對(duì)象一起使用。為了理解顏色模型工作的基本知識(shí),我們將只使用一個(gè)缺省的顏色模型,其顏色組件由 RGB 值和一個(gè)緩沖類型(存儲(chǔ) 8 位的 RGB 顏色值加上一個(gè) alpha 通道)組成。這一緩沖類型由 BufferedImage 類中的常量 TYPE_INT_ARGB 指定,它意味著每個(gè)像素要用一個(gè) int 值。每個(gè)像素的值是以 8 位字節(jié)形式存儲(chǔ)一個(gè) alpha 組件加上 RGB 顏色組件。我們可以用給定的寬度和高度創(chuàng)建一個(gè)這種類型的 BufferedImage 對(duì)象,代碼語(yǔ)句如下:

  int width = 200;
  int height = 300;
  BufferedImage image = new BufferedImage(width,
  height,BufferedImage.TYPE_INT_ARGB);

  這段代碼創(chuàng)建了一個(gè) BufferedImage 對(duì)象,它代表一個(gè) 200 像素寬、300 像素高的圖像。為了應(yīng)用這個(gè)圖像,我們需要有圖形上下文,而 BufferedImage 對(duì)象的 createGraphics() 方法就返回一個(gè)與該圖像相關(guān)的 Graphics2D 對(duì)象:

  int width = 200;
  Graphics2D g2D = image.createGraphics();

  使用 g2D 對(duì)象的操作會(huì)修改 BufferedImage 對(duì)象 image 的像素。利用這個(gè)對(duì)象,您現(xiàn)在完全有能力應(yīng)用 BufferedImage 對(duì)象。您可以繪制形狀、圖像、GeneralPath 對(duì)象或任何別的東西,還可以為圖形上下文設(shè)置 alpha 組合對(duì)象。您同時(shí)還擁有 Graphics2D 對(duì)象提供的全部仿射變形能力。

  如果要從 BufferedImage 對(duì)象獲取單個(gè)像素,可以通過調(diào)用它的 getRGB() 方法,并提供該像素的 x,y 坐標(biāo)作為 int 類型的參數(shù)。這個(gè)像素會(huì)按 TYPE_INT_ARGB 格式以 int 類型返回,它由四個(gè) 8 位的值(代表 alpha 值和 RGB 顏色組件)組成一個(gè) 32 位字。同時(shí) getRGB() 還有一個(gè)重載的版本,它從一部分圖像數(shù)據(jù)中返回一個(gè)像素?cái)?shù)組。您也可以通過調(diào)用 setRGB() 方法來設(shè)置單個(gè)像素。前兩個(gè)參數(shù)是該像素的坐標(biāo)值,第三個(gè)參數(shù)是待設(shè)定的值,類型為 int。這個(gè)方法也有一個(gè)版本可以設(shè)置像素?cái)?shù)組的值。

  至此我們已經(jīng)完成了像素操作的學(xué)習(xí)。下面我們要建立一個(gè) applet,它在 Wrox 徽標(biāo)背景上使 BufferedImage 對(duì)象具有動(dòng)畫效果。我們的示例還將演示怎樣能讓圖像局部透明。applet 的基本內(nèi)容如下所示:

  import java.awt.*;
  import java.awt.image.*;
  import java.awt.geom.*;
  import javax.swing.*;

  public class ImageDrawDemo extends JApplet
  {
  // The init() method to initialize everything...
  // The start() method to start the animation...
  // The stop() method to stop the animation...
  // The ImagePanel class defining the panel displaying the animation...
  // Data members for the applet...
  }

  創(chuàng)建一個(gè)圖像

  一個(gè)子圖形是一個(gè)小的圖形圖像,可以將其繪制在靜態(tài)圖像以創(chuàng)建動(dòng)畫。要?jiǎng)?chuàng)建動(dòng)畫效果,您只要隨著時(shí)間推移,在不同的位置和方向上繪制子圖形。當(dāng)然,利用坐標(biāo)系的變形可以使之簡(jiǎn)化許多。游戲經(jīng)常使用子圖形 — 由于您只需要在一個(gè)靜態(tài)背景上繪制子圖形,所以可以使動(dòng)畫所占用的處理器的時(shí)間大大減少。我們對(duì)使用 BufferedImage 對(duì)象的興趣意味著我們將不再花費(fèi)精力去研究減少處理器時(shí)間的最佳技術(shù),而是把注意力放在理解怎樣才能在一個(gè)程序內(nèi)部創(chuàng)建和使用圖像上。

  我們的 BufferedImage 對(duì)象看上去如圖 1 中的圖像:

  圖 1. BufferedImage 子圖形

  這個(gè)圖像是一個(gè)以 spriteSize 為邊長(zhǎng)的正方形。圖像其它部分的尺寸值都與這個(gè)邊長(zhǎng)相關(guān)。實(shí)際上這里只有兩個(gè)幾何實(shí)體,一條線和一個(gè)圓,都在不同位置和方向重復(fù)出現(xiàn)。如果我們創(chuàng)建一個(gè) Line2D.Double 對(duì)象代表線,創(chuàng)建一個(gè) Ellipse2D.Double 對(duì)象代表圓,那么我們就可以通過移動(dòng)用戶坐標(biāo)系和畫這兩個(gè)對(duì)象中的一個(gè)或其它的對(duì)象而畫出整個(gè)圖像。

  如果是按真正面向?qū)ο蟮姆椒?,?yīng)該定義一個(gè)類代表一個(gè)子圖形,可能是作為 BufferedImage 的一個(gè)子類,但由于我們是在探索使用 BufferedImage 對(duì)象的技巧,因此用一個(gè) createSprite() 方法來畫出 BufferedImage 對(duì)象上的子圖形會(huì)更適合我們的目的。因?yàn)樵摲椒ㄖ皇俏覀兊?applet 類的一個(gè)成員,所以我們將為 applet 添加數(shù)據(jù)成員以存儲(chǔ)任何需要的數(shù)據(jù)。您可以把我們將使用的數(shù)據(jù)成員插入到 applet 類中,如下所示:

  double totalAngle; // Current angular position of sprite
  double spriteAngle; // Rotation angle of sprite about its center
  ImagePanel imagePanel; // Panel to display animation

  BufferedImage sprite; // Stores reference to the sprite
  int spriteSize = 100; // Diameter of the sprite
  Ellipse2D.Double circle; // A circle - part of the sprite
  Line2D.Double line; // A line - part of the sprite

  // Colors used in sprite
  Color[] colors = {Color.red , Color.yellow, Color.green , Color.blue,
  Color.cyan, Color.pink , Color.magenta, Color.orange};

  java.util.Timer timer; // Timer for the animation
  long interval = 50; // Time interval msec between repaints

  這些成員的一般用途可以從注釋中清楚地看到。下面我們要看一看開發(fā)代碼時(shí)它們是怎樣被使用的。

  createSprite() 方法需要做的第一件事就是創(chuàng)建 BufferedImage 對(duì)象 sprite,然后我們還需要一個(gè) Graphics2D 對(duì)象用于在 sprite 圖像上繪畫。下面就是完成這些操作的代碼:

  BufferedImage createSprite(int spriteSize)
  {
  // Create image with RGB and alpha channel
  BufferedImage sprite = new BufferedImage(spriteSize, spriteSize,
  BufferedImage.TYPE_INT_ARGB);

  Graphics2D g2D = sprite.createGraphics(); // Context for buffered image
  // plus the rest of the method...
  }

  sprite 對(duì)象的寬和高的值都是 spriteSize,圖像的類型為 TYPE_INT_ARGB,就是說每個(gè)像素的 alpha 值和顏色組件是以一個(gè)單獨(dú)的 int 值存儲(chǔ)的,而顏色是以 8 位的紅、綠、藍(lán)組件的形式存儲(chǔ)的。這意味著我們的 sprite 圖像將占用 40,000 字節(jié),這只是瀏覽一個(gè)網(wǎng)頁(yè)會(huì)占用的內(nèi)存的很小一部分。而這并不影響網(wǎng)頁(yè)的下載時(shí)間,因?yàn)樵趫?zhí)行 applet 的時(shí)候,這部分內(nèi)存是在本地機(jī)器上被分配的。除了作為網(wǎng)頁(yè)本身的 HTML 文件的內(nèi)容外,下載時(shí)間還取決于 applet 的 .class 文件的大小,以及在它執(zhí)行時(shí)下載的圖像或其它文件。

    創(chuàng)建一個(gè)透明的背景

  在 sprite 圖像中,alpha 通道是很重要的,因?yàn)槲覀兿M尘澳芡耆该?。在繪畫過程中,只有 sprite 對(duì)象本身應(yīng)該是可見的,而不是整個(gè) 100×100 的矩形圖像。我們可以很容易地實(shí)現(xiàn)這一目的,只要開始先使整個(gè) sprite 圖像區(qū)域透明(即,alpha 值為 0.0f),然后把我們想要畫的圖形繪制在上面,使之不透明(alpha 值為 1.0f)。以下是使整個(gè)圖像透明的代碼:

  // Clear image with transparent alpha by drawing a rectangle
  g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
  Rectangle2D.Double rect = new Rectangle2D.Double(0,0,spriteSize,spriteSize);
  g2D.fill(rect);

  我們首先使用 AlphaComposite 對(duì)象按照 CLEAR 規(guī)則設(shè)置 alpha 合成值,把顏色組件設(shè)置為零,又通過設(shè)置 alpha 值為 0.0f,使之透明。然后我們填充一個(gè)覆蓋整個(gè)圖像區(qū)域的矩形。我們不必設(shè)置顏色值,因?yàn)楦鶕?jù) CLEAR 規(guī)則,每個(gè)像素的前景和背景色所占成分都是零,所以這兩者都不參與像素的生成。但我們?nèi)砸畛湓摼匦?,因?yàn)檫@將確定被操作的圖像像素。

  這里,我們可以稍微了解一下怎樣控制圖像的質(zhì)量。

  著色微調(diào)

  對(duì)著色操作的許多方面而言,都有一個(gè)在質(zhì)量和速度間選擇的問題。著色操作就像大多數(shù)事情一樣 — 質(zhì)量是需要代價(jià)的,而這里的代價(jià)就是處理時(shí)間。所有的著色操作都有缺省設(shè)置,其中存在一個(gè)選擇,缺省設(shè)置是特定于平臺(tái)的,但您可以通過調(diào)用用于著色的 Graphics2D 對(duì)象的 setRenderingHint() 方法自己選擇。雖然只有一些微調(diào),如果您的計(jì)算機(jī)不支持與您指定的微調(diào)相對(duì)應(yīng)的著色操作選項(xiàng),這些微調(diào)就無法生效。

  通過添加以下對(duì) createSprite() 方法的調(diào)用,可以確保得到由我們的 alpha 合成操作可能生成的最好效果。

  BufferedImage createSprite(int spriteSize)
  {
  // Create image with RGB and alpha channel
  BufferedImage sprite = new BufferedImage(spriteSize, spriteSize, BufferedImage.TYPE_INT_ARGB);

  Graphics2D g2D = sprite.createGraphics(); // Context for buffered image

  // Set best alpha interpolation quality
  g2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
  RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

  // Clear image with transparent alpha by drawing a rectangle
  g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
  Rectangle2D.Double rect = new Rectangle2D.Double(0,0,spriteSize,spriteSize);
  g2D.fill(rect);

  // plus the rest of the method...
  }

  RenderingHints 類定義了多種著色微調(diào),它們存儲(chǔ)在一個(gè)映射集的 Graphics2D 對(duì)象里。 setRenderingHint() 方法的參數(shù)是一個(gè)鍵以及對(duì)應(yīng)的鍵值。在我們的代碼中,第一個(gè)參數(shù)是代表 alpha 合成微調(diào)的鍵,第二個(gè)參數(shù)是該微調(diào)的值。該微調(diào)的其它可能的值有 VALUE_ALPHA_INTERPOLATION_DEFAULT,代表平臺(tái)缺省值;以及 VALUE_ALPHA_INTERPOLATION_SPEED,代表追求速度而不是質(zhì)量。

  您還可以為下面的鍵提供微調(diào):

  鍵 描述
  KEY_ANTIALIASING決定是否使用抗鋸齒。當(dāng)著色有傾斜角度的線時(shí),通常會(huì)得到一組階梯式的像素排列,使這條線看上去不平滑,經(jīng)常被稱為 鋸齒狀圖形??逛忼X是一種技術(shù),它設(shè)置有傾斜角度的線的像素亮度,以使線看起來更平滑。因此,這個(gè)微調(diào)是用來決定在著色有傾斜角度的線時(shí)是否在減少鋸齒狀圖形上花費(fèi)時(shí)間??赡艿闹涤?VALUE_ANTIALIAS_ON, _OFF 或 _DEFAULT。
  KEY_COLOR_RENDERING控制顏色著色的方式??赡艿闹涤?VALUE_COLOR_RENDER_SPEED, _QUALITY 或 _DEFAULT。
  KEY_DITHERING控制如何處理抖動(dòng)。抖動(dòng)是用一組有限的顏色合成出一個(gè)更大范圍的顏色的過程,方法是給相鄰像素著色以產(chǎn)生不在該組顏色中的新的顏色幻覺??赡艿闹涤?VALUE_DITHER_ENABLE, _DISABLE 或 _DEFAULT。
  KEY_FRACTIONALMETRICS文本的質(zhì)量??赡艿闹涤?VALUE_FRACTIONALMETRICS_ON, _OFF 或 _DEFAULT。
  KEY_INTERPOLATION確定怎樣做內(nèi)插。

  在對(duì)一個(gè)源圖像做變形時(shí),變形后的像素很少能夠恰好對(duì)應(yīng)目標(biāo)像素位置。在這種情況下,每個(gè)變形后的像素的顏色值不得不由周圍的像素決定。

  內(nèi)插就是實(shí)現(xiàn)上述過程。有許多可用的技術(shù)。可能的值,按處理時(shí)間從最多到最少,是 VALUE_INTERPOLATION_BICUBIC, _BILINEAR 或 _NEAREST_NEIGHBOR。

  KEY_RENDERING 確定著色技術(shù),在速度和質(zhì)量之間進(jìn)行權(quán)衡??赡艿闹涤?VALUE_RENDERING_SPEED, _QUALITY 或 _DEFAULT。

  KEY_TEXT_ANTIALIASING 確定對(duì)文本著色時(shí)是否抗鋸齒。可能的值有 VALUE_TEXT_ANTIALIASING_ON, _OFF 或 _DEFAULT。

  我們繞得已經(jīng)夠遠(yuǎn)了。讓我們回到繪制 sprite 上……

您可能感興趣的文章:
  • java數(shù)字圖像處理基礎(chǔ)使用imageio寫圖像文件示例
  • Java圖像處理工具類
  • 詳解Java如何實(shí)現(xiàn)圖像灰度化
  • 使用Java進(jìn)行圖像處理的一些基礎(chǔ)操作
  • Java實(shí)現(xiàn)的圖像查看器完整實(shí)例
  • 舉例解析Java的圖像緩沖技術(shù)的使用
  • Java圖像之自定義角度旋轉(zhuǎn)(實(shí)例)
  • 簡(jiǎn)述Java圖像傾斜方法及實(shí)例
  • Java圖像處理教程之正片疊底效果的實(shí)現(xiàn)

標(biāo)簽:亳州 紅河 大興安嶺 岳陽(yáng) 武威 鄭州 馬鞍山 拉薩

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Java應(yīng)用程序中創(chuàng)建圖像》,本文關(guān)鍵詞  Java,應(yīng)用程序,中,創(chuàng)建,圖像,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Java應(yīng)用程序中創(chuàng)建圖像》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Java應(yīng)用程序中創(chuàng)建圖像的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    千阳县| 玉山县| 清徐县| 章丘市| 南漳县| 尤溪县| 塔城市| 赣州市| 石渠县| 永新县| 昭觉县| 朔州市| 大丰市| 大新县| 志丹县| 阳泉市| 博客| 兴城市| 塔河县| 新安县| 韶山市| 通江县| 衡山县| 巴中市| 湖北省| 佛山市| 察雅县| 安国市| 云梦县| 滦南县| 武清区| 阿合奇县| 宁夏| 大埔县| 罗平县| 西乌珠穆沁旗| 星座| 漳平市| 潮州市| 建始县| 日照市|