Как обрезать изображение с определенной формой в Blackberry? - PullRequest
3 голосов
/ 06 января 2012

Привет всем благодаря прочтению моего ответа надеюсь, вы можете помочь мне

Я работаю над кадрированием изображения в blackberry. В моей заявке содержатся 3 основные вещи.

1) Загрузить изображение на экран

2) выберите форму области обрезки

3) отобразить обрезанное изображение на следующем экране без потери его формы

Step1: я могу сделать часть загрузки изображения

шаг2: используя Меню, я просто добавляю 4 типа фигур

       1)Circle

        2)Rectangle with rounded shape

       3)Star 

       4)Cloud 

используя меню, когда он щелкает по любому пункту меню, тогда конкретное изображение формы будет отображаться на экране.

мы можем дать движение этому изображению, потому что мы должны предоставить ему возможность выбрать любую часть изображения.

шаг 3: После исправления положения мы позволим пользователю обрезать, используя меню. когда он нажимает на пункт меню «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

1 Ответ

6 голосов
/ 07 января 2012

Используя другое фиктивное изображение, можно определить, какие пиксели исходного изображения необходимо удалить (мы можем сделать их прозрачными). Хотя это может быть не оптимальное решение, но оно может быть применено к любой геометрической фигуре, которую мы можем нарисовать на BlackBerry.

Проверьте следующие шаги:

  • Создайте новое растровое изображение (dummyImage) того же размера, что и исходное изображение (myImage).
  • Нарисуйте (заполните) целевую геометрическую фигуру на нем, используя определенный цвет (* 1 010 *). * * +1011
  • Теперь для каждого пикселя 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

...