JavaFX實現android中的9patch功能

來源:互聯網
上載者:User

 9patch是android中直接支援的一個特性。在做背景圖片和遊戲中是比較常見的一種技術。在css中做背景很常見。其原理就是把一張圖切成9塊(9patch),如下圖(比較懶,直接引用自網路):

保持1、3、7、9地區圖片分別在新產生圖片的左上方、右上方、左下角、右下角,2、8地區做repeat-x操作,4、6地區做repeat-y操作,5地區做repeat-x-y操作。這樣即可解決圖片自適應大小問題。而android中的9patch在原圖片的上下左右分別添加了一個像素,上圖產生的4條黑色線條,這樣即可決定9地區的寬高大小了,其中右邊和底部的黑色線條為決定內容部分,其實也沒那神秘。

  JavaFX中沒有這個強大功能,不過知道了原理,這裡本人實現了一個javafx版,完全滿足日常開發工作:

 代碼如下 複製代碼

/**
 * javafx實現android的9patch
 *
 * @author zhou
 *
 */
public final class NinePatch{
  private Image origin;
  private int top;
  private int right;
  private int bottom;
  private int left;

  public NinePatch(Image origin, int topRightBottomLeft){
    this(origin, topRightBottomLeft, topRightBottomLeft);
  }

  public NinePatch(Image origin, int topBottom, int leftRight){
    this(origin, topBottom, leftRight, topBottom, leftRight);
  }

  public NinePatch(Image origin, int top, int right, int bottom, int left){
    if(left + right > origin.getWidth())
      throw new IllegalArgumentException("left add right must less than origin width");

    if(top + bottom > origin.getHeight())
      throw new IllegalArgumentException("top add bottom must less than origin height");

    this.origin = origin;
    this.top = top;
    this.right = right;
    this.bottom = bottom;
    this.left = left;
  }

  /**
   * 產生指定寬高圖片
   *
   * @param scaledWidth
   * @param scaledHeight
   * @return
   */
  public Image generate(int scaledWidth, int scaledHeight){
    WritableImage result = new WritableImage(scaledWidth, scaledHeight);
    PixelReader reader = origin.getPixelReader();
    PixelWriter writer = result.getPixelWriter();
    int originHCenterWidth = (int) origin.getWidth() - right - left;
    int originVCenterWidth = (int) origin.getHeight() - top - bottom;

    /* first row */
    writer.setPixels(0, 0, left, top, reader, 0, 0);
    for(int y = 0; y < top; y++){
      for(int x = left; x < scaledWidth - right; x++){
        writer.setArgb(x, y, reader.getArgb(left + (x - left) % originHCenterWidth, y));
      }
    }

    writer.setPixels(scaledWidth - right, 0, right, top, reader, (int) origin.getWidth() - right, 0);

    /* second row */
    for(int y = top; y < scaledHeight - bottom; y++){
      for(int x = 0; x < left; x++){
        writer.setArgb(x, y, reader.getArgb(x, top + (y - top) % originVCenterWidth));
      }
    }

    for(int y = top; y < scaledHeight - bottom; y++){
      for(int x = left; x < scaledWidth - right; x++){
        writer.setArgb(x, y,
            reader.getArgb(left + (x - left) % originHCenterWidth, top + (y - top) % originVCenterWidth));
      }
    }

    for(int y = top; y < scaledHeight - bottom; y++){
      for(int x = scaledWidth - right; x < scaledWidth; x++){
        writer.setArgb(x, y,
            reader.getArgb((int) origin.getWidth() + x - scaledWidth, top + (y - top) % originVCenterWidth));
      }
    }

    /* third row */
    writer.setPixels(0, scaledHeight - bottom, left, bottom, reader, 0, (int) origin.getHeight() - bottom);
    for(int y = scaledHeight - bottom; y < scaledHeight; y++){
      for(int x = left; x < scaledWidth - right; x++){
        writer.setArgb(x, y,
            reader.getArgb(left + (x - left) % originHCenterWidth, (int) origin.getHeight() + y - scaledHeight));
      }
    }
    writer.setPixels(scaledWidth - right, scaledHeight - bottom, right, bottom, reader,
        (int) origin.getWidth() - right, (int) origin.getHeight() - bottom);

    return result;
  }

  /**
   *
   * @param gc
   * @param x
   * @param y
   * @param scaledWidth
   * @param scaledWidth
   */
  public void draw(GraphicsContext gc, int x, int y, int scaledWidth, int scaledHeight){
    gc.drawImage(generate(scaledWidth, scaledHeight), x, y);
  }

}

這裡沒有使用黑色像素條(原始)的方式實現,因為知道了top、right、bottom、left就可以確定一個圖片的9塊地區了,後面就是做repeat操作了。

後面也很容易實作類別似google的不指定topRightBottomLeft方式直接從xxx.9.png載入的功能。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.