2012-01-06 97 views
3

大家好,感謝閱讀我的答案希望你能幫助我如何在黑莓中裁剪特定形狀的圖像?

我正在處理黑莓圖像裁剪。在我的應用程序包含3個主要的東西

1)裝載屏幕

2)上的圖像選擇裁剪區域

3)顯示的是裁剪圖像在下一個屏幕上與出失去其形狀

第一步的形狀:ⅰ可以完成圖像加載部分

第二步:使用菜單我只是添加了4種形狀的

 1)Circle 

     2)Rectangle with rounded shape 

     3)Star 

     4)Cloud 

使用菜單,當他點擊任何菜單項時,那個特定的形狀圖像將顯示在屏幕上。

我們可以給該圖像提供運動,因爲我們必須讓他選擇圖像的任何部分。

step3:確定位置後,我們將允許用戶使用菜單進行裁剪。 當他點擊菜單項「CROP」時。然後我們根據形狀裁剪圖像和圖像應顯示在下一屏幕上

注:下面的代碼只爲長方形的工作,但我想 使用各種形狀

這是我的示例代碼::

import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.system.Display; 
import net.rim.device.api.ui.Field; 
import net.rim.device.api.ui.Graphics; 
import net.rim.device.api.ui.Manager; 
import net.rim.device.api.ui.MenuItem; 
import net.rim.device.api.ui.Screen; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.XYEdges; 
import net.rim.device.api.ui.XYRect; 
import net.rim.device.api.ui.component.BitmapField; 
import net.rim.device.api.ui.component.Dialog; 
import net.rim.device.api.ui.component.Menu; 
import net.rim.device.api.ui.container.MainScreen; 
import net.rim.device.api.ui.container.VerticalFieldManager; 
import net.rim.device.api.ui.decor.BackgroundFactory; 

public class ClipMove extends MainScreen{ 
    Bitmap circle_frame,rectangle_frame,star_frame,cloud_frame,image,selected_frame; 
    BitmapField frmae_field; 
    private int padding_x=0,padding_y=0; 
    private VerticalFieldManager vrt_mgr; 
    public ClipMove() { 
     //Here my shape images are transparent 
     circle_frame=Bitmap.getBitmapResource("circle.gif"); 
     rectangle_frame=Bitmap.getBitmapResource("rect1.png"); 
     star_frame=Bitmap.getBitmapResource("star.gif"); 
     cloud_frame=Bitmap.getBitmapResource("cloud.gif"); 

     //this is my actual image to crop 
     image=Bitmap.getBitmapResource("sample.jpg"); 

     vrt_mgr=new VerticalFieldManager(){ 
      protected void sublayout(int maxWidth, int maxHeight) { 
       super.sublayout(Display.getWidth(),Display.getHeight()); 
       setExtent(Display.getWidth(),Display.getHeight()); 
      } 

     }; 
     vrt_mgr.setBackground(BackgroundFactory.createBitmapBackground(image)); 


     add(vrt_mgr); 
    } 

    protected void makeMenu(Menu menu, int instance) { 
     super.makeMenu(menu, instance); 
     menu.add(new MenuItem("Rect",0,0) { 
      public void run() { 
       // TODO Auto-generated method stub 
       vrt_mgr.deleteAll(); 
       selected_frame=rectangle_frame; 
       frmae_field=new BitmapField(rectangle_frame); 
       vrt_mgr.add(frmae_field); 
       vrt_mgr.invalidate(); 

      } 
     }); 

     menu.add(new MenuItem("Circle",0,0) { 
      public void run() { 
       // TODO Auto-generated method stub 
       vrt_mgr.deleteAll(); 
       selected_frame=circle_frame; 
       frmae_field=new BitmapField(circle_frame); 
       vrt_mgr.add(frmae_field); 
       vrt_mgr.invalidate(); 

      } 
     }); 

     menu.add(new MenuItem("Star",0,0) { 
      public void run() { 
       // TODO Auto-generated method stub 
       vrt_mgr.deleteAll(); 
       selected_frame=star_frame; 
       frmae_field=new BitmapField(star_frame); 
       vrt_mgr.add(frmae_field); 
       vrt_mgr.invalidate(); 
      } 
     }); 

     menu.add(new MenuItem("Cloud",0,0) { 
      public void run() { 
       // TODO Auto-generated method stub 
       vrt_mgr.deleteAll(); 
       selected_frame=cloud_frame; 
       frmae_field=new BitmapField(cloud_frame); 
       vrt_mgr.add(frmae_field); 
       vrt_mgr.invalidate(); 
      } 
     }); 
     menu.add(new MenuItem("Crop",0,0) { 
      public void run() { 
       // TODO Auto-generated method stub 
       Field f=vrt_mgr.getField(0); 
//    XYRect rect=getFieldExtent(f); 
       XYRect rect=new XYRect(padding_x, padding_y,frmae_field.getBitmapWidth(),frmae_field.getBitmapHeight()); 
       Bitmap crop = cropImage(image, rect.x, rect.y, 
          rect.width, rect.height); 
       synchronized (UiApplication.getEventLock()) { 
        UiApplication.getUiApplication().pushScreen(new sampleScreen(crop,selected_frame)); 
       } 

      } 
     }); 

    } 
    protected boolean navigationMovement(int dx, int dy, int status, int time) { 
     if(frmae_field!=null){ 
      padding_x=padding_x+dx; 
      padding_y=padding_y+dy; 
      XYEdges edge=new XYEdges(padding_y, 0, 0, padding_x); 
      frmae_field.setPadding(edge); 
      vrt_mgr.invalidate(); 
      return true; 
     }else { 
      return false; 
     } 

    } 

    public void DisplayMessage(final String str) 
    { 
     UiApplication.getUiApplication().invokeLater(new Runnable() { 
      public void run() { 
       Dialog.inform(str); 
      } 
     }); 
    } 
    public XYRect getFieldExtent(Field fld) { 
      int cy = fld.getContentTop(); 
      int cx = fld.getContentLeft(); 
      Manager m = fld.getManager(); 
      while (m != null) { 
       cy += m.getContentTop() - m.getVerticalScroll(); 
       cx += m.getContentLeft() - m.getHorizontalScroll(); 
       if (m instanceof Screen) 
        break; 
       m = m.getManager(); 
      } 
      return new XYRect(cx, cy, fld.getContentWidth(), fld.getContentHeight()); 
     } 
    // this logic only useful for rectangler shape 
    public Bitmap cropImage(Bitmap image, int x, int y, int width,int height) { 
      Bitmap result = new Bitmap(width, height); 
      Graphics g = Graphics.create(result); 
      g.drawBitmap(0, 0, width, height, image, x, y); 
      return result; 
    } 
} 
//this is my next screen to show the croped image 
class sampleScreen extends MainScreen 
{ 
    VerticalFieldManager manager; 
    public sampleScreen(final Bitmap img,final Bitmap back) { 
     manager=new VerticalFieldManager(){ 
      protected void paint(Graphics graphics) { 
       graphics.drawBitmap(0, 0, img.getWidth(), img.getHeight(), img, 0, 0); 
       super.paint(graphics); 
      } 
      protected void sublayout(int maxWidth, int maxHeight) { 
       super.sublayout(img.getWidth(), img.getHeight()); 
       setExtent(img.getWidth(), img.getHeight()); 
      } 
     }; 
     BitmapField field=new BitmapField(back); 
     field.setPadding(0, 0, 0, 0); 
     manager.add(field); 
     add(manager); 
    } 
} 

我的屏幕截圖:

enter image description here

enter image description here

回答

6

通過使用另一個虛擬圖像,所以能夠確定需要被刪除的原始圖像的像素(我們可以使它們透明的)。雖然它可能不是最佳解決方案,但它可以應用於我們可以在BlackBerry上繪製的任何幾何圖形。

檢查以下步驟:

  • 創建相同尺寸的新的位圖圖像(dummyImage)作爲 源圖像(myImage)。
  • 使用定義的顏色在其上繪製(填充)目標幾何形狀 (fillColor)。
  • 現在爲myImage每個像素,如果dummyImage 相同的像素包含fillColor則保持不變,否則使這個像素 通過分配零(0)完全透明的。
  • 現在myImage已經差不多準備好了,需要修剪此圖片以便 透明像素移除。

以下代碼將在圖像上應用圓形裁剪。 (但不會修剪透明像素)。

package mypackage; 

import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.system.Display; 
import net.rim.device.api.ui.Color; 
import net.rim.device.api.ui.Graphics; 
import net.rim.device.api.ui.MenuItem; 
import net.rim.device.api.ui.component.BitmapField; 
import net.rim.device.api.ui.component.Menu; 
import net.rim.device.api.ui.container.MainScreen; 

class MyScreen extends MainScreen { 
    private Bitmap myImage = Bitmap.getBitmapResource("img/myImage.jpeg"); 
    private BitmapField _bf; 

    public MyScreen() { 
     _bf = new BitmapField(myImage); 
     adjustBitmapMargin(); 
     add(_bf); 
    } 

    private void adjustBitmapMargin() { 
     int x = (Display.getWidth() - myImage.getWidth())/2; 
     int y = (Display.getHeight() - myImage.getHeight())/2; 
     _bf.setMargin(y, 0, 0, x); 
    } 

    protected void makeMenu(Menu menu, int instance) { 
     menu.add(miCropCircle); 
     super.makeMenu(menu, instance); 
    } 

    private MenuItem miCropCircle = new MenuItem("Crop - Circle", 0, 0) { 
     public void run() { 
      cropImage(); 
     } 
    }; 

    private void cropImage() { 
     int width = myImage.getWidth(); 
     int height = myImage.getHeight(); 

     // get original data from the image 
     int myImageData[] = new int[width * height]; 
     myImage.getARGB(myImageData, 0, width, 0, 0, width, height); 

     // get default color of a newly created bitmap 
     int defaultColors[] = new int[1 * 1]; 
     (new Bitmap(1, 1)).getARGB(defaultColors, 0, 1, 0, 0, 1, 1); 

     int defaultColor = defaultColors[0]; 
     int fillColor = Color.RED; 
     int diameter = 200; 

     // dummy data preparation 
     Bitmap dummyImage = new Bitmap(width, height); 
     Graphics dummyImageGraphics = Graphics.create(dummyImage); 
     dummyImageGraphics.setColor(fillColor); 
     int startX = width/2 - diameter/2; 
     int startY = height/2 - diameter/2; 
     dummyImageGraphics.fillArc(startX, startY, diameter, diameter, 0, 360); 
     int dummyData[] = new int[width * height]; 
     dummyImage.getARGB(dummyData, 0, width, 0, 0, width, height); 

     // filling original data with transparent value. 
     int totalPixels = width * height; 
     for (int i = 0; i < totalPixels; i++) { 
      if (dummyData[i] == defaultColor) { 
       myImageData[i] = 0; 
      } 
     } 

     // set new data 
     myImage.setARGB(myImageData, 0, width, 0, 0, width, height); 

     // redraw screen 
     _bf.setBitmap(myImage); 
     adjustBitmapMargin(); 
     invalidate(); 

     // free up some memory here 
     defaultColors = null; 
     dummyImage = null; 
     dummyData = null; 
     dummyImageGraphics = null; 
    } 
} 


輸出上面的代碼:

Output generated by above code snippet

+0

非常感謝你,在這兒工作了一圈,但我需要知道如何實現其他形狀請指導我\ – 2012-01-07 06:05:21

+0

檢查代碼的'// dummy data preparation'部分,在那裏我使用'dummyImageGraphics.fillArc(..)'繪製了一個圓。只需要在那裏繪製所需的幾何形狀。例如,您可以使用'Graphics.drawFillPath(...)'繪製星星。你也可以在那裏繪製任何圖像(星星/雲)。 – Rupak 2012-01-07 09:44:02

+0

你我完成了親愛的謝謝 – 2012-01-07 10:19:55