BlackBerry - рисовать изображение на экране

Как нарисовать png изображения с определенным размером и положением на экране?


person Community    schedule 15.09.2009    source источник


Ответы (4)


Изменить размер изображения

 public EncodedImage sizeImage(EncodedImage image, int width, 
  int height) {
  EncodedImage result = null;

  int currentWidthFixed32 = Fixed32.toFP(image.getWidth());
  int currentHeightFixed32 = Fixed32.toFP(image.getHeight());

  int requiredWidthFixed32 = Fixed32.toFP(width);
  int requiredHeightFixed32 = Fixed32.toFP(height);

  int scaleXFixed32 = Fixed32.div(currentWidthFixed32,
    requiredWidthFixed32);
  int scaleYFixed32 = Fixed32.div(currentHeightFixed32,
    requiredHeightFixed32);

  result = image.scaleImage32(scaleXFixed32, scaleYFixed32);
  return result;
 }

Эта функция будет использоваться в приведенном ниже коде.

Просто раскрашивая изображения

http://img268.imageshack.us/img268/9918/bb8310.png

Давайте раскрасим 9 изображений в виде таблицы, изображения разные по размеру, но мы изменим их размер до 80x80 и дадим им поля 10 пикселей.

Предположим, у вас есть 9 изображений png в ресурсах вашего проекта.

  1. Загрузить изображения
  2. Изменить размер изображений
  3. Нарисуйте изображения на каждом событии рисования в определенной позиции

Код:

class Scr extends MainScreen {
 int mImgWidth = 80;
 int mImgHeight = 80;
 int mImgMargin = 10;
 String fileNames[] = { "1.png", "2.png", "3.png", "4.png", "5.png",
   "6.png", "7.png", "8.png", "9.png" };
 EncodedImage[] mImages;

 public Scr() {
 super();
  prepareImages();
 }

 private void prepareImages() {
  mImages = new EncodedImage[fileNames.length];
  for (int i = 0; i < fileNames.length; i++) {
   EncodedImage image = EncodedImage
     .getEncodedImageResource(fileNames[i]);
   mImages[i] = sizeImage(image, mImgWidth, mImgHeight);
  }
 }

 protected void paint(Graphics graphics) {
  paintImages(graphics);
  super.paint(graphics);
 }

 private void paintImages(Graphics graphics) {
  int scrWidth = Display.getWidth();
  int columns = scrWidth / (mImgWidth + 2 * mImgMargin);
  int rows = mImages.length / columns
    + (mImages.length % columns > 0 ? 1 : 0);
  for (int i = 0; i < rows; i++) {
   for (int j = 0; j < columns; j++) {
    int posX = j * (mImgWidth + 2 * mImgMargin) + mImgMargin;
    int posY = i * (mImgHeight + 2 * mImgMargin) + mImgMargin;
    EncodedImage image = mImages[i * columns + j];
    graphics.drawImage(posX, posY, mImgWidth, mImgHeight,
      image, 0, 0, 0);
   }
  }
 }
}

Простое рисование изображений - оптимизация

Взгляните на метод paint () в Scr. При каждом обновлении перерисовывается вся таблица изображений, что означает 9 вызовов drawImage для каждой краски. Что, если мы просто возьмем форму этой таблицы и используем ее в методе paint ()?

class ScrOpt extends MainScreen {
 int mScrWidth = Display.getWidth();
 int mScrHeight = Display.getHeight();
 int mImgWidth = 80;
 int mImgHeight = 80;
 int mImgMargin = 10;
 String fileNames[] = { "1.png", "2.png", "3.png", "4.png", "5.png",
   "6.png", "7.png", "8.png", "9.png" };
 EncodedImage[] mImages;
 Bitmap mImgTable;

 public ScrOpt() {
  super();
  prepareImages();
  mImgTable = paintImages();
 }

 private void prepareImages() {
  mImages = new EncodedImage[fileNames.length];
  for (int i = 0; i < fileNames.length; i++) {
   EncodedImage image = EncodedImage
     .getEncodedImageResource(fileNames[i]);
   mImages[i] = sizeImage(image, mImgWidth, mImgHeight);
  }
 }

 private Bitmap paintImages() {
  Bitmap result = new Bitmap(mScrWidth, mScrHeight);
  Graphics graphics = new Graphics(result);
  int scrWidth = mScrWidth;
  int columns = scrWidth / (mImgWidth + 2 * mImgMargin);
  int rows = mImages.length / columns
    + (mImages.length % columns > 0 ? 1 : 0);
  for (int i = 0; i < rows; i++) {
   for (int j = 0; j < columns; j++) {
    int posX = j * (mImgWidth + 2 * mImgMargin) + mImgMargin;
    int posY = i * (mImgHeight + 2 * mImgMargin) + mImgMargin;
    EncodedImage image = mImages[i * columns + j];
    graphics.drawImage(posX, posY, mImgWidth, mImgHeight, image, 0,
      0, 0);
   }
  }
  return result;
 }

 protected void paint(Graphics graphics) {  
  super.paint(graphics);
  graphics.drawBitmap(0, 0, mScrWidth, mScrHeight, mImgTable, 0, 0);
 }
}

Вы можете оптимизировать его еще больше, с помощью метода paintBackground ()

Использование BitmapField

Все вышесказанное касается рисования изображений прямо на экране с помощью Графика. Иногда это здорово - когда вы хотите отобразить некоторую анимацию или фоновое изображение. Но что, если вы хотите сохранить стандартный интерфейс пользователя и использовать изображения в качестве полей?

альтернативный текст http://img142.imageshack.us/img142/7485/bb83102.png < / а>

Прямой путь - это BitmapField

class ScrBmpField extends MainScreen {
 int mImgWidth = 80;
 int mImgHeight = 80;
 int mImgMargin = 10;
 String fileNames[] = { "1.png", "2.png", "3.png", "4.png", "5.png",
   "6.png", "7.png", "8.png", "9.png" };
 BitmapField[] mBmpFields;

 public ScrBmpField() {
  super(VERTICAL_SCROLL|VERTICAL_SCROLLBAR);
  prepareBmpFields();  
 }

 private void prepareBmpFields() {
  mBmpFields = new BitmapField[fileNames.length];
  for (int i = 0; i < fileNames.length; i++) {
   EncodedImage image = EncodedImage
     .getEncodedImageResource(fileNames[i]);
   image = sizeImage(image, mImgWidth, mImgHeight);
   mBmpFields[i] = 
       new BitmapField(image.getBitmap(), FOCUSABLE|FIELD_HCENTER);
   mBmpFields[i].setMargin(mImgMargin, mImgMargin, 
       mImgMargin, mImgMargin);
   add(mBmpFields[i]);
  }
 }
}

Использование BitmapField - настраиваемый макет

альтернативный текст http://img9.imageshack.us/img9/403/bb83103.png < / а>

Чтобы установить пользовательские позиции BitmapFields в диспетчере, вы можете реализовать диспетчер с настраиваемым макетом < / а>:

class ScrLayout extends MainScreen {
    int mScrWidth = Display.getWidth();
    int mScrHeight = Display.getHeight();
    int mImgWidth = 80;
    int mImgHeight = 80;
    int mImgMargin = 10;
    String fileNames[] = { "1.png", "2.png", "3.png", "4.png", "5.png",
            "6.png", "7.png", "8.png", "9.png" };
    BitmapField[] mBmpFields;

    public ScrLayout() {
        super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
        prepareBmpFields();
    }

    private void prepareBmpFields() {
        LayoutManager manager = new LayoutManager();
        add(manager);
        mBmpFields = new BitmapField[fileNames.length];
        for (int i = 0; i < fileNames.length; i++) {
            EncodedImage image = EncodedImage
                    .getEncodedImageResource(fileNames[i]);
            image = sizeImage(image, mImgWidth, mImgHeight);
            mBmpFields[i] = 
                new BitmapField(image.getBitmap(), FOCUSABLE);
            manager.add(mBmpFields[i]);
        }
    }

    class LayoutManager extends VerticalFieldManager {
        public LayoutManager() {
            super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
        }

        protected void sublayout(int width, int height) {
            int columns = mScrWidth / (mImgWidth + 2 * mImgMargin);
            for (int i = 0, j = 0; i < mBmpFields.length; i++) {
                int posX = j * (mImgWidth + 2 * mImgMargin) + mImgMargin;
                int posY = i * (mImgHeight + 2 * mImgMargin) + mImgMargin;
                Field field = mBmpFields[i];
                layoutChild(field, mImgWidth, mImgHeight);
                setPositionChild(field, posX, posY);

                j = (j == columns - 1) ? 0 : j + 1;
            }
            setExtent(mScrWidth, mScrHeight);
        }
        public int getPreferredWidth() {
            return mScrWidth;
        }
        public int getPreferredHeight() {
            return mScrHeight;
        }
    }
}
person Maksym Gontar    schedule 18.09.2009

Где-то в функции инициализации:

 Image myImage = Image.createImage("/myimage.png");

И в функции рисования вашего холста:

 g.drawImage(myImage, posX, posY, Graphics.TOP|Graphics.LEFT);

(где g - объект Graphics, который вы получаете из функции рисования)

edit: исправлена ​​небольшая ошибка, указанная в комментариях

person Toad    schedule 15.09.2009

Если вы используете net.rim.device.api.system.PNGEncodedImage или один из других классов, расширенных из net.rim.device.api.system.EncodedImage, вы можете использовать метод scaleImage32 (int scaleX, int scaleY) (доступен в ОС 4.2 и новее), чтобы масштабировать изображение до нужного размера. Имейте в виду, что scaleX и scaleY, хотя и набраны как int, на самом деле являются net.rim.device.api.math.Fixed32, чтобы изображение отображалось в половинном размере:

EncodedImage halfSize = myImage.scaleImage32(Fixed32.toFP(2), Fixed32.toFP(2));

Или для изображения вдвое оригинального размера:

EncodedImage twiceSize = myImage.scaleImage32(Fixed32.tenThouToFP(5000), Fixed32.tenThouToFP(5000));
person Richard    schedule 15.09.2009
comment
Единственным недостатком является то, что в коде используются только классы обода, и поэтому он не переносится на любое другое Java-устройство. - person Toad; 15.09.2009
comment
Верно, но ваш ответ соответствует только одному из двух требований, указанных в OP. - person Richard; 15.09.2009

private VerticalFieldManager mainBackVerticalFieldManager = null;

int deviceWidth = Display.getWidth();
int deviceHeight = Display.getHeight();    

mainBackVerticalFieldManager   = new VerticalFieldManager(VerticalFieldManager.NO_VERTICAL_SCROLL|VerticalFieldManager.NO_VERTICAL_SCROLLBAR){
        protected void paint(Graphics graphics) {
            graphics.clear();
            graphics.drawBitmap(0, 0, deviceWidth,deviceHeight,Bitmap.getBitmapResource(Constants.PURCHASE_SUMMARY_BG), 0,0);
            super.paint(graphics);
        };
    };

Здесь вы можете изменить deviceWidth и высоту по своему усмотрению.

person Dhiral Pandya    schedule 19.09.2011