Reputation: 2862
Hi all thanks to read my answer hope you can help me
I am working on Image cropping in blackberry. In my application contain 3 main things.
1)Load the image on the screen
2)select the shape of the cropping area
3)display that cropping image on next screen with out losing its shape
Step1: i can done the image loading part
step2: using Menu i just add the 4 types of shapes
1)Circle
2)Rectangle with rounded shape
3)Star
4)Cloud
using menu when he click on any menu item ,then that particular shape image will display on the screen.
we can give the movement to that image because we have to provide him to select any portion of the image.
step3: After fix the position then we will allow the user to crop using menu. when he click on menu item " CROP". then we have to crop the image according the shape and that image should display on the next screen
Note: Following code working only for Rectangular shape but i want to use all shapes
This is my sample code ::
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);
}
}
My screen shots:
Upvotes: 3
Views: 1064
Reputation: 3674
By using another dummy image, it is possible to determine which pixels of the original image needs to be deleted (we can make them transparent). Though It may not be the optimal solution, but it can be applied for any geometric figure we can draw on BlackBerry.
Check following steps:
dummyImage
) of same dimension as the
source image (myImage
).fillColor
).myImage
, if the same pixel of dummyImage
contains fillColor
then keep it unchanged, else make this pixel
fully transparent by assigning zero (0
) to it.myImage
is almost ready, need to trim this image for
transparent pixel removal.Following code will apply a circular crop on a image. (but won't trim the transparent pixels).
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 of the above code:
Upvotes: 6