歡迎您光臨本站 註冊首頁

Java線程式控制制的圖像分割與合成

←手機掃碼閱讀     火星人 @ 2014-03-26 , reply:0

摘 要:使用Java對WEB靜態圖像進行分割重組,然後根據用戶的交互操作合成顯示,並利用線程對程序的併發性加以控制,從而達到圖像顯示的動態性和交互性效果。
  關鍵詞:Java語言 類Class 線程Thread

  Java是一種面向對象的編程語言。它具有與平台無關、面向對象、動態、安全等特點,允許直接使用多線程方式進行編程,對程序進行併發控制。 Java還支持分散式網路操作,從而能夠方便地進行網路文件對象的存取。利用Java語言本身提供的繪圖功能,可以繪製一些簡單的圖形。而對於複雜圖形,一般先用繪圖軟體製成圖像,然後採用Java所提供的方法對圖像下載並進行處理和控制,從而實現靜態圖像的動態顯示。
1 Java圖像處理與線程的併發控制
1.1 Java圖像處理
  Java語言提供了豐富的類(Class)、介面(Interface)以及相應的調用方法(Method)。使用這些類或介面,可以定義自己的類或子類,充分利用Java面向對象的特性進行編程。在java.awt包中,提供了專門的Image類,它是1種抽象類,可提供抽象的方法描繪圖片的一些共同特性。而在Applet類和Tookit類中都提供了2種getImage()方法下載圖像,分別根據絕對地址和相對地址查詢所要下載的圖像。通常採用相對地址的下載方法,它的語法定義及功能如下:
  1.public Image getImage(URL url,String name)
  功能:根據相對地址下載圖像。
  參數:url??URL(統一資源定位)基地址,
name??圖像文件名。
  獲取圖像后就可以調用Graphics類提供的drawImage()方法顯示圖像。
  2.public drawImage(Image img,int x,int y,observer)
  功能:在指定位置顯示圖像。
  參數:img??待顯示圖像,x??橫坐標,y??縱坐標,observer??圖像監視器,用來監視圖像的下載情況,接受圖像裝載信息(當圖像完全載入時返回True,否則返回False)。
  在顯示圖像時,通常希望獲得對圖像的控制,從而以自己喜歡的各種方式實現媒體播放。為此,Java專門提供了用於跟蹤包括圖像和聲音等多媒體對象的ImageObserver類和MediaTracker類,在本文程序中主要用到的是跟蹤多幅圖像狀態的MediaTracker類。
1.2 Java多線程併發功能
  目前,線程(Thread)已經為許多操作系統和應用開發系統所採用。線程是程序的單個控制流,具有順序程序的特點,但是線程不是1個程序,它僅僅是程序的1個執行序列。線程具有很強的併發功能,在同一時刻可能有多個線程同時處於執行狀態。線程是動態的,具有一定的生命周期,分別經歷從創建、執行、阻塞直到消亡的過程。Java語言中提供了專門的Thread類,以支持直接的多線程編程。Thread類提供了對線程的控制方法,如Start (),Stop(),Run()、Suspend()、resume()、Sleep()以及Run()方法等等,它們可以對線程的狀態進行控制。並可以運用SetPriority()方法設置線程的運行優先順序。Thread類的定義方法如下:
  Thread(ThreadGroup group,Runable target,String name)
  SetPriority()用來設置線程的優先順序。線程優先順序是1個介於MINPRIORITY(在類中定義為1)和MAXPRIORITY(在類中定義為10)之間的整數。線程不同的優先順序決定了不同線程之間的切換。
2 Java圖像分割與合成的演算法及實現
  Java程序首先將一個完整的圖像下載,然後將其分割成20個單元拼圖,即分為5行4列。在本例中特地將第20幅圖像單元設為1個空白圖像,以便拼圖時用戶交互操作使用。這些參數分別定義在相應的變數中。
  final int XCELLS=5;  //每行拼圖的數目
  final int YCELLS=4;//每列拼圖的數目
  final int ALLCELLS=20;//分割元素的數目
  final int EMPTY=19;//將第20單元,即cells[19]置成
//空白圖像
  然後將這些圖像分割單元存於1個Cell類數組cells[]中,在這裡Cell類中含有圖像以及它的起始位置和當前位置,其具體定義如下:
  class Cell
  {int sx,sy; //起始位置
  int cx,cy; //當前位置
  Image img; //單元圖像
  public Cell(Image img,int x,int y) //Cell類構造函數
  {this.img=img;
  sx=x;sy=y;} //給起始位置賦值為x,y
  }
  為了對每個圖像分割單元進行狀態跟蹤,還需要建立1個MediaTracker類的實體(instance),然後調用addImage()方法,為每個要跟蹤的圖像指定1個唯一的標識符。標識符決定了圖像獲取時的優先順序並使得圖像能夠獨立完整地進行處理。
  MediaTracker tracker=new MediaTracker(this)
  //為當前使用類建立1個MediaTracker實體,用於跟蹤類
  //上的圖像
  cells[EMPTY]=new Cell(createEmpty(),toPoint(EMPTY).x,toPoint(EMPTY).y);
  tracker.addImage(cells[EMPTY].img,0);
  //調用createEmpty()方法產生空白圖像,並加入到所跟蹤
  //的cells數組中20單元
  void setPosition(int x,int y)  //設置單元圖像當前位置
  {cx=x;cy=y;}

  各個圖像單元的位置存放於位置數組position里:
  int position[][]=new int[XCELLs][YCELLS]
  這樣就可以使用Cell類數組cells[]對圖像的各個單元進行操作,從而將各個單元圖像進行合成顯示,並通過position[][]數組改變各個單元的位置。為了對各單元進行併發操作,需要對線程加以控制,並通過滑鼠事件和按鍵事件控制進程的開始、睡眠和進行等狀態變化,其實現方法如下 (僅以run()方法為例):
  Thread imageThread=null; //定義線程imageThread,初始
//值為空
  public void run()
  {imageThread.setPriority(Thread.MINPRIORITY);//設置線
//程執行優先順序別

  try
    {imageThread.sleep(2000);//線程睡眠等待2000ms
    }catch(InterruptedException e){}
  first=changeArray();//調用changeArray()方法隨機改變圖
//像單元位置
  while(!loaded)//判斷圖像若未被跟蹤載入,則調用相關
//方法跟蹤並載入圖像
    {repaint();
    try
     {imageThread.sleep(100);
     }catch(InterruptedException e){System.out.println(e);}
    }
  }
  changeArray()方法用來隨機地改變圖像單元的位置,其實現方法如下:
  boolean changeArray()
  {
  int source[]=new int[20];
  int full[]=new int[20];
  for(int i=0;i     {
    int r=(int)(Math.random()*20);
    while(full[r]!=0)
    r=(r+(int)(Math.random()*20))%20;
    source[i]=r;
    full[r]=1;
    }
  int pos=0;
  for(int i=0;i     {
    Point p=toPoint(source[pos]);
    cells[pos].setPosition(p.x,p.y);
    position[p.x][p.y]=pos;
    }
  x=cells[EMPTY].cx;
  y=cells[EMPTY].cy;
  return(false);
  }
  當applet執行後點擊滑鼠,線程就被啟動,開始裝載圖像並執行changeArray()隨機選擇1個位置來移動圖像單元,此時可以使用鍵盤移動圖像上的任意單元到任何位置。在這裡還有一個重要內容就是怎樣將圖像分割成許多的單元,我們可以通過引用CropImageFilter方法來分割圖像,它是1個分割圖像過濾器。其實現方法如下:
  Image crop(int pos)
  {//pos參數為調用函數給出的圖像單元位置號
  Point p=toPoint(pos);//將位置號轉化為坐標形式
  ImageFilter filter=new CropImageFilter(xside*p.x,yside*p.y,xside,yside);
  //在給定坐標和長寬的絕對矩形區域內創建分割圖像過
  //濾器實體filter
  ImageProducer producer=new FilteredImageSource(baseImage.getSource(),filter;)

//由原圖像和分割圖像過濾器實體創建新的圖像

      //產生器producer
  return createImage(producer);//由圖像產生器producer產生
//圖像並返回
  }

  通過以上步驟,整個圖像的分割與合成顯示就完成了。本程序主要利用了crop()、changeArray()、mousedown()、Thread()等方法以及幾個表示程序運行狀態的布爾變數實現了一個線程式控制制和動感圖像相結合的圖像處理過程。

作者單位:山東東營石油大學計算機系(257062)

[火星人 ] Java線程式控制制的圖像分割與合成已經有668次圍觀

http://coctec.com/docs/linux/show-post-190046.html