how to crop image with particular shape in Blackberry?
大家好,感谢阅读我的回答希望你能帮助我
我正在研究黑莓中的图像裁剪。在我的应用程序中包含 3 个主要内容。
1)在屏幕上加载图像
2)选择裁剪区域的形状
3) 在下一个屏幕上显示该裁剪图像而不会丢失其形状
Step1:我可以完成图像加载部分
第二步:使用菜单我只添加了 4 种形状
1 2 3 4 5 6 7 | 1)Circle 2)Rectangle with rounded shape 3)Star 4)Cloud |
当他点击任何菜单项时使用菜单,然后该特定形状的图像将显示在屏幕上。
我们可以赋予该图像移动,因为我们必须让他选择图像的任何部分。
step3: 固定位置后,我们将允许用户使用菜单进行裁剪。
当他单击菜单项" CROP"时。然后我们必须根据形状裁剪图像并且该图像应该显示在下一个屏幕上
Note: Following code working only for Rectangular shape but i want to
use all shapes
这是我的示例代码 ::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | 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); } } |
我的屏幕截图:
通过使用另一个虚拟图像,可以确定需要删除原始图像的哪些像素(我们可以使它们透明)。虽然它可能不是最佳解决方案,但它可以应用于我们可以在 BlackBerry 上绘制的任何几何图形。
检查以下步骤:
-
创建一个新的位图图像 (
dummyImage ) 与
源图像 (myImage )。 -
使用定义的颜色在其上绘制(填充)目标几何形状
(fillColor )。 -
现在对于
myImage 的每个像素,如果dummyImage 的相同像素
包含fillColor 然后保持不变,否则制作这个像素
通过为其分配零 (0 ) 来完全透明。 -
现在
myImage 几乎准备好了,需要修剪这个图像
透明像素去除。
以下代码将在图像上应用圆形裁剪。 (但不会修剪透明像素)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 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; } } |
上述代码的输出: