I have one PNG image and am applying it to all the screens as background. Its resolution is 360x480 because I started programming for 9800 simulator. I am developing for OS 6.0. When I test my app for 9700 simulator having screen resolution 480x360, the image covers only half the screen. I have researched and learnt about using Fixed32 and scale and I have applied it as well. But still the background seems to cause an issue. I have only one image in resource folder. How to handle this one image to apply suitably for all different blackberry devices
You have to resize the image based to screen width and height to fit to the screen you are are running.
For this the following methods will use.
public static 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;
}
After resizeing use below method for cropping.
public static Bitmap cropBitmap(Bitmap original, int width, int height) {
Bitmap bmp = new Bitmap(width, height);
int x = (original.getWidth() / 2) - (width / 2); // Center the new size by width
int y = (original.getHeight() / 2) - (height / 2); // Center the new size by height
int[] argb = new int[width * height];
original.getARGB(argb, 0, width, x, y, width, height);
bmp.setARGB(argb, 0, width, 0, 0, width, height);
return bmp;
Create bitmap image as follow.
EncodedImage eImage = EncodedImage.getEncodedImageResource("img/new.png" );
EncodedImage bitimage=sizeImage(eImage,Display.getWidth(),Display.getHeight());
Bitmap image=cropBitmap(bitimage.getBitmap(),Display.getWidth(),Display.getHeight());
pass above bitmap to you manager.
Now set the returned bitmap as background to screen.It worked for me.Hope this will help to you.
To set your image with required width and height use Bitmap scale; And if you want to put your image as Background then put the bitmap image to VerticalFieldManager like this:
For all devices it works:
Bitmap bit=Bitmap.getBitmapResource("background.png");
Bitmap scalingBitmap=new Bitmap(Device.getWidth(),Device.getHeight()); //here you can give any size.Then it sets the image according to your required width and height;
bit.scaleInto(scalingBitmap, Bitmap.FILTER_LANCZOS); //This is important;
VerticalFieldManager mainVertical=new VerticalFieldManager()
{
//Here Device.getWidth() and Device.getHeight(); These two are your Blackberry Device width and height;(According your 9800 it takes 480x360)
protected void paint(Graphics g)
{
g.clear();
g.drawBitmap(0, 0, Device.getWidth(),Device.getHeight(), scalingBitmap, 0, 0);
super.paint(g);
}
protected void sublayout(int maxWidth, int maxHeight)
{
super.sublayout(Device.getWidth(),Device.getHeight());
setExtent(Device.getWidth(),Device.getHeight());
}
};
add(mainVertical);
This is enough.
Related
zbar engine sample source(zbarimg.c) shows the following.
https://github.com/ZBar/ZBar/blob/master/zbarimg/zbarimg.c
size_t bloblen = width * height;
unsigned char *blobdata = malloc(bloblen);
MagickExportImagePixels(images, 0, 0, width, height, "I", CharPixel, blobdata);
I'd like to see the blobdata.
How can I save the blobdata to file?
I made save_imgdata function to save blobdata.
int save_imgdata(char* imgf, int width, int height, char *raw)
{
PixelWand *p_wand = NULL;
PixelIterator *iterator = NULL;
PixelWand **pixels = NULL;
unsigned long x, y;
char hex[128];
//MagickWandGenesis();
p_wand = NewPixelWand();
PixelSetColor(p_wand, "gray");
//PixelSetColor(p_wand, "white");
MagickWand *m_wand = NewMagickWand(); //CORE_RL_wand_.lib;
MagickSetImageDepth(m_wand, 8);
MagickNewImage(m_wand, width, height, p_wand);
// Get a new pixel iterator
iterator = NewPixelIterator(m_wand);
for (y = 0; y<height; y++) {
// Get the next row of the image as an array of PixelWands
pixels = PixelGetNextIteratorRow(iterator, &x);
// Set the row of wands to a simple gray scale gradient
for (x = 0; x<width; x++) {
sprintf(hex, "#%02x", *raw++);
//sprintf(hex, "#%02%x02%x02x", *raw, *raw, *raw); raw++;
PixelSetColor(pixels[x], hex);
}
// Sync writes the pixels back to the m_wand
PixelSyncIterator(iterator);
}
MagickWriteImage(m_wand, imgf);
DestroyMagickWand(m_wand);
return 0;
}
The call of save_imgdata("imgw.bmp", width, height, blobdata)
save 24bpp image.
What's wrong of save_imgdata?
I want it saves 8bpp gray image file.
Don't bother iterating and building dynamic color/pixel values -- It's slow and resource intensive. If the data came from an export method, than use the import method to restore.
int save_imgdata(char* imgf, int width, int height, void * raw)
{
MagickWand * wand;
PixelWand * bgcolor;
bgcolor = NewPixelWand();
PixelSetColor(bgcolor, "WHITE");
wand = NewMagickWand();
MagickNewImage(wand, width, height, bgcolor);
bgcolor = DestroyPixelWand(bgcolor);
MagickSetImageDepth(wand, 8);
MagickSetImageColorspace(wand, GRAYColorspace);
MagickImportImagePixels(wand, 0, 0, width, height, "I", CharPixel, raw);
MagickQuantizeImage(wand,
256, // Reduce to 8bpp
GRAYColorspace, // Match colorspace
0, // Calculate optimal tree depth
MagickTrue, // Use dither ? This changes in IM-7
MagickFalse); // Messure Error
MagickWriteImage(wand, imgf);
wand = DestroyMagickWand(wand);
return 0;
}
I have a List Items(an Image and text)on BB Screen,
My requirement is to set an image border(So that Image Separation will be done on List Items) to image on BB Screen
Could any one help?
Here My Code:
public void drawListRow(ListField list, Graphics g, int index, int y,
int width) {
String title = (String) listElements.elementAt(index);
Bitmap image = (Bitmap) listImage.elementAt(index);
int LEFT_OFFSET = 2;
int TOP_OFFSET = 8;
int xpos = LEFT_OFFSET;
int ypos = TOP_OFFSET + y;
int w = image.getWidth();
int h = image.getHeight();
g.drawBitmap(xpos, ypos, w, h, image, 4, 6);
xpos = w + 20;
g.setFont(myFont);
g.setColor(Color.BLACK);
g.drawText(title, xpos, ypos);
}
i hope i got your question right and would suggest you drawing a rectangle around the image like that:
g.setColor(Color.RED);
g.drawRect(xpos - 1, ypos - 1, w + 1, h + 1);
This would draw the rectangle around your image without overlapping it. For more details on why you need these adjustments of the position and the size of the rectangle you can check on the documentation of Graphics class here http://www.it.uc3m.es/florina/docencia/j2me/midp/docs/api/javax/microedition/lcdui/Graphics.html
I have written the following code here the background image is displaying but the image did not cover the full background
private Bitmap background;
int mWidth = Display.getWidth();
int mHeight = Display.getHeight();
public MyScreen()
{
// Set the displayed title of the screen
//backgroundBitmap = Bitmap.getBitmapResource("slidimage.png");
final Bitmap background = Bitmap.getBitmapResource("slidimage.png");
HorizontalFieldManager vfm = new HorizontalFieldManager(USE_ALL_HEIGHT | USE_ALL_WIDTH) {
public void paint(Graphics g) {
g.drawBitmap(0, 0,mWidth, mHeight, background, 0, 0);
super.paint(g);
}
};
add(vfm);
public static Bitmap resizeBitmap(Bitmap image, int width, int height)
{
int rgb[] = new int[image.getWidth()*image.getHeight()];
image.getARGB(rgb, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
int rgb2[] = rescaleArray(rgb, image.getWidth(), image.getHeight(), width, height);
Bitmap temp2 = new Bitmap(width, height);
temp2.setARGB(rgb2, 0, width, 0, 0, width, height);
return temp2;
}
You can use the above method to resize the image
just pass the image to be resized and its width and height .
and the function will return the resized image .
where rescale Array is the below method
private static int[] rescaleArray(int[] ini, int x, int y, int x2, int y2)
{
int out[] = new int[x2*y2];
for (int yy = 0; yy < y2; yy++)
{
int dy = yy * y / y2;
for (int xx = 0; xx < x2; xx++)
{
int dx = xx * x / x2;
out[(x2 * yy) + xx] = ini[(x * dy) + dx];
}
}
return out;
}
I had an custom editfield
public class Custom_EditField extends EditField {
int width, row;
Custom_EditField(long style, int width, int row) {
super(style);
this.width = width;
this.row = row;
}
protected void layout(int width, int height) {
width = this.width;
height = this.row;
super.layout(width, Font.getDefault().getHeight() * row);
super.setExtent(width, Font.getDefault().getHeight() * row);
}
public int getPreferredHeight() {
return Font.getDefault().getHeight() * row;
}
public int getPreferredWidth() {
return width;
}
public void paint(Graphics graphics) {
super.paint(graphics);
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
int labelWidth = getFont().getAdvance(getLabel());
graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
graphics.drawText(this.getText(), 0, 0);
}
}
When I type a full line of word in the editfield, it will cause and error. It seem like cannot auto go to next line.
The arguments to the layout method in BlackBerry UI are maximums, and your custom code makes no attempt to honor those maximums when setting the field extent. This will cause problems with your layout. Also, the paint() method is not the best place to alter drawing for text fields, because it doesn't understand text wrapping. If you want to alter how the text is drawn, but after the wrapping has been performed, you want to override drawText instead.
This is approximately what you want, but you will need to do some more tweaking to make it work the way you expect:
protected void layout(int maxWidth, int maxHeight) {
super.layout(maxWidth, Math.min(maxHeight, Font.getDefault().getHeight() * row));
super.setExtent(maxWidth, Math.min(maxHeight, Font.getDefault().getHeight() * row));
}
public int drawText(Graphics graphics,
int offset,
int length,
int x,
int y,
DrawTextParam drawTextParam) {
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
int labelWidth = getFont().getAdvance(getLabel());
graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
graphics.drawText(this.getText().substring(offset, offset + length), x, y);
}
This is my custom layout which was same as android linear layout
public class Custom_TopField extends VerticalFieldManager {
private static final int FIELD_HEIGHT = 70;
private String _text;
Custom_TopField(int color, String text) {
super(Manager.NO_VERTICAL_SCROLL);
_text = text;
Background background = BackgroundFactory.createSolidBackground(color);
setBackground(background);
}
protected void sublayout(int width, int height) {
width = Math.min(width, getPreferredWidth());
height = Math.min(height, getPreferredHeight());
setExtent(width, height);
}
public int getPreferredHeight() {
return FIELD_HEIGHT;
}
public int getPreferredWidth() {
return Display.getWidth();
}
public void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
Font font = Font.getDefault().derive(Font.BOLD, 65);
graphics.drawRect(0, 0, rectWidth, rectHeight);
graphics.drawText(_text, rectWidth / 2, 10);
graphics.setFont(font);
graphics.setColor(Color.WHITE);
super.paint(graphics);
}
}
Output = background red and font = black
What I want is background red, font white, font size 40.
I also want to know how to create widget programmatically?
To set the font to white and the size to 40 change the paint as follows:
public void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
Font font = Font.getDefault().derive(Font.BOLD, 40);
graphics.setColor(Color.WHITE);
graphics.setFont(font);
graphics.drawRect(0, 0, rectWidth, rectHeight);
graphics.drawText(_text, rectWidth / 2, 10);
super.paint(graphics);
}