12-01-2011 12:33 PM
Solved! Go to Solution.
12-01-2011 01:25 PM
I think the basic process is you take the pixel data in img_t, render it to a pixmap, then put the pixmap into the context buffer.
Check out "Sample: Drawing using Blits, Pixmaps, and Buffers" in the IDE help,
Scott
12-01-2011 05:51 PM
You can use the img library to load an image, and you can use the screen library to draw on the screen, but the two do not have an explicit meeting in the middle. That is, there's nothing in img that says "draw this to the screen", and there's nothing in screen that says "draw this image".
The screen library provides buffers...screen buffers that are related directly to the screen, and pixmap buffers that can be related to offscreen images and other renderings.
A few of the example apps in the "NDK Examples" on github.com/blackberry show various bits and pieces of what you need to do. For example, look at the "GestureSample" app. In that example, the "load_image" function starts the process of reading an image file. It sets up callback functions, one of which, "decode_setup", is called by the library to handle the image content. It allocates a screen buffer, then gets a pointer to the buffer's data area, putting that pointer into the img structure, which the img library will use to actually load the image bits into the screen buffer. The image thus ends up being placed directly into a screen buffer, which eventually gets to the display. It's a bit of a trick in a sense, because the two api's are unrelated, but you are basically copying and pasting a buffer pointer from one api into the load sequence of another. Alternatively, you would be more likely to allocate a pixmap buffer, and set up the pointer so the image loads into that buffer. To actually render it later, you would go back to the screen library, and the "screen_blit" function to copy the image, or some portion of it, to whereever you want it to go in screen co-ordinates.
When you blit an image from one buffer into a screen buffer, you also seem to need to take care of cropping the blit at the screen buffer's boundaries, as cropping does not seem to be applied automatically.
In summary, these two libraries are very (very) low-level, and require a fair amount of intensely grungy code to do something as simple as getting an image from a file to the screen.
Higher level packages, such as Qt, take care of all this stuff for you. You have to decide whether to get down at the low level and worry about a lot of stuff, or let the higher level packages take care of it for you.
12-01-2011 06:30 PM
Thanks a bunch. That was two great answers that lead me on the right track. I was actualy reading through the tutorial that Scott suggested when Ken's post came in and was thinking of the pixmap route. Sounds like thats what Ken is suggesting also even with that detailed explanation of the example file.
I now I am choosing to do things a bit harder but I believe knowing these core ideas of how things work from the ground up is a good idea to learn from the start so I dont fall into bad habbits later. I'm on a mission to understand!
Be back soon with a good solution to do this. Special thanks to Scott and Ken.
Addtionaly while I work on doing this maybe someone can answer the question of how concerned with qulity of the images I can use? Seems PNG is a usable format and thats a pretty high resolution base.
12-01-2011 08:49 PM
What do you think about this so far on the right track with what you were saying of changing pointers to pixmap?
screen_context_t homeContext = 0;
screen_window_t homeWindow = 0;
static const char *homeGroup = "Home Windows";
screen_buffer_t homeBuffer;
int hformat_w = SCREEN_FORMAT_RGBA8888;
int hshap[4] = { 0, 0, 1, 1 };
int iusage = SCREEN_USAGE_WRITE | SCREEN_USAGE_NATIVE;
int place = 0;
unsigned char* temp = NULL;
screen_pixmap_t welcomeLogo;
screen_buffer_t imgBuffer;
img_t mindLogo;
img_lib_t ilib = NULL;
const char *LP = "assets/logo.png";
int largeLogo;
int logolib;
logolib = img_lib_attach(&ilib);
mindLogo.format = IMG_FMT_PKBE_ARGB8888;
mindLogo.flags |= IMG_FORMAT;
mindLogo.flags = 0;
mindLogo.w = 600;
mindLogo.flags |= IMG_W;
mindLogo.h = 400;
mindLogo.flags |= IMG_H;
largeLogo = img_load_file(ilib, LP, NULL, &mindLogo);
screen_create_pixmap(&welcomeLogo, homeContext);
screen_set_pixmap_property_iv(welcomeLogo, SCREEN_PROPERTY_FORMAT, &hformat_w);
screen_set_pixmap_property_iv(welcomeLogo, SCREEN_PROPERTY_USAGE, &iusage);
screen_create_pixmap_buffer(welcomeLogo);
imgBuffer = calloc(place, sizeof(mindLogo)); //change to pixmap buffer?
screen_get_pixmap_property_pv(welcomeLogo, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&imgBuffer);
screen_get_buffer_property_pv(imgBuffer, SCREEN_PROPERTY_POINTER, (void **)&temp);
12-02-2011 10:58 PM
As others have alluded to, there are a few ways you might consider rendering data to the screen.
In your code, it seems you were heading down path #2, but you were allocating imgBuffer yourself, which does not make sense in that case.
Here's an example I just threw together which takes approach #2.
screen_context_t ctx;
screen_window_t window;
screen_buffer_t winbuf;
screen_pixmap_t pixmap;
screen_buffer_t pixbuf;
int pixsize[2] = { 200, 200 }; // create a pixmap @ 200x200
int winsize[2] = { 600, 600 }; // create a window @ 600x600
int rect[4] = { 0, 0, 600, 600 }; // bounding box for the full window
int fmt = SCREEN_FORMAT_RGBA8888;
int usage = SCREEN_USAGE_READ | SCREEN_USAGE_WRITE;
unsigned long *dataptr;
int i;
screen_create_context(&ctx, SCREEN_APPLICATION_CONTEXT);
screen_create_window_type(&window, ctx, SCREEN_APPLICATION_WINDOW);
screen_set_window_property_iv(window, SCREEN_PROPERTY_FORMAT, &fmt);
screen_set_window_property_iv(window, SCREEN_PROPERTY_BUFFER_SIZE, winsize);
screen_create_window_buffers(window, 1);
screen_get_window_property_pv(window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)&winbuf);
sleep(1);
screen_create_pixmap(&pixmap, ctx);
screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_USAGE, &usage);
screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_FORMAT, &fmt);
screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_BUFFER_SIZE, pixsize);
screen_create_pixmap_buffer(pixmap);
screen_get_pixmap_property_pv(pixmap, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)&pixbuf);
screen_get_buffer_property_pv(pixbuf, SCREEN_PROPERTY_POINTER, (void**)&dataptr);
for (i=0; i < pixsize[0] * pixsize[1]; i++) {
// fill with some sort of pattern.
// in the imglib example, you would load your img into the memory that dataptr points to
dataptr[i] = 0xff000000 | (0x00010000 * (i % pixsize[0])) | (0x00000100 * (i / pixsize[1]));
}
int blits[] = { SCREEN_BLIT_SOURCE_X, 0,
SCREEN_BLIT_SOURCE_Y, 0,
SCREEN_BLIT_SOURCE_WIDTH, pixsize[0],
SCREEN_BLIT_SOURCE_HEIGHT, pixsize[1],
SCREEN_BLIT_DESTINATION_X, 100,
SCREEN_BLIT_DESTINATION_Y, 100,
SCREEN_BLIT_DESTINATION_WIDTH, 400,
SCREEN_BLIT_DESTINATION_HEIGHT, 400,
SCREEN_BLIT_END };
screen_blit(ctx, winbuf, pixbuf, blits);
screen_post_window(window, winbuf, 1, rect, SCREEN_WAIT_IDLE);
What this does is:
-creates a window 600x600 in size
-creates a pixmap 200x200 in size
-retrieves a pointer to the pixmap data buffer
-renders a pattern into the data buffer
-blits the pixmap onto the window at location (100,100), and scales it to size 400 x 400.
-posts the full window to the screen
I may have been a bit overly wordy in my blitting example.. you can blit the entire pixmap scaled to the size of the entire window buffer by just specifying SCREEN_BLIT_END, but I felt the additional information may prove a useful reference for you if you wished to scale or move the pixmap around the window.
In your use case, instead of rendering a pattern to the pixmap, you would load your PNG data there instead.
Hope this serves as a useful starting point for you.
12-03-2011 12:36 AM
also, pls ignore my sleep(1).. was testing something else ![]()
12-16-2011 12:40 AM - edited 12-16-2011 12:41 AM
Wow. Thanks! So sorry for the delayed response finals and term project all caught up with me the last few weeks and I had to buckle in. I will be giving this a workout tomarrow. Hopefully I can create a nice little class to share.
03-26-2012 12:22 PM
Sorry,
Could you please post this example with the explicit usage of img_load_file and assigning the pointer to the image, as many people (including me are newbies) and don't understand how to do that. Providing couple of more lines of code would be more helpful then any verbal explanations. Besides, someone else suggested using Qt library that I believe is not available yet, is misleading. Please correct me if I am wrong?
Thanks,
03-29-2012 11:02 AM
Hi Brandon,
Have you been able to figure out the code that reads from img_t (read from a png or jpg file) data and displays it as bitmap? If so could you please provide a few line of code.
Thanks,