Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Convert bb::cascades::Image to QImage?

The more I work with the Cascades Image class the more I hate it. Why on earth did the Cascades team decide to create a crippled image class of their own rather than use the powerful Qt Qimage class? I need to determine the width and height of a Cascades Image object, but there are no accessor functions to find this out, nor is there any way to access the associated ImageData which holds this information.

 

I am downloading images from the web and downscaling them, which is easy with QImage, so I convert the raw image data to QImage first, manipulate it, then convert it into a Cascades ImageData and build a Cascades Image from it. That works fine, but now I need to go the other way. I have a Cascades Image and I want to convert it to a Qt QImage. There just doesn't seem to be any way to extract anything from Image that can be used to build a QImage.



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.
Retired
PBernhardt
Posts: 749
Registered: ‎12-16-2008
My Device: BlackBerry Z30

Re: Convert bb::cascades::Image to QImage?

In Cascades, images are all loaded asynchronously. This prevents loading an image from blocking the UI or making it feel unresponsive, but also makes it a bit harder to determine properties about the image like size.

 

You can use ImageTracker to figure out that sort of thing: https://developer.blackberry.com/native/reference/cascades/bb__cascades__imagetracker.html

 

Not sure that you can actually get the bytes back out of an Image or ImageView though, unfortunately. Why do you need them? Those classes are really just containers to display the image. Could you do what you need with some of the other image utility classes like ImageData or ImageConverter?

Paul Bernhardt
Application Development Consultant
BlackBerry
@PBernhardt

Did this answer your question? Please accept this post as the solution.
Found a bug? Report it to the Developer Issue Tracker
Please use plain text.
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Convert bb::cascades::Image to QImage?

[ Edited ]

Yes, I am aware of the async nature of images, and of ImageTracker, but it doesn't solve my situation since I need to get the image data out of an already downloaded image, so ImageTracker is not helpful. Qt::QImage is likewise asynchronous, but it manages to provide a wealth of info about the image as well as many transformation functions once it is downloaded so there is no reason bb::cascades::Image couldn't do the same.

 

I'll explain why it is important to me to be able to convert an Image to a QImage. The latter is a very powerful image manipulation tool, whereas the former is just a... box for image data. For instance, QImage can be used as a drawing canvas, allowing you to start from scratch or an extant image and annotate it with lines and circles and text, etc. Also, QImage can actually scale an image up or down, resulting in a new image with changed dimensions, unlike Cascades Image, where you can change the size the image is displayed at by ImageView, but the image itself actually remains the same size and consumes the same memory.

 

The resizing issue is particularly important in my app. I am downloading potentially hundreds of images up to a megabyte or two in size and using them as thumbnails only one or two hundred pixels wide/high. Once downloaded I don't need to keep them around in original form, consuming all that memory (a gig or more) so I need to truly resize them rather than just change the way they display. QImage has numerous resizing tools, and the result is a new image with the dimensions specified. A 1.5MB image converted to a 100px thumbnail only takes up a few tens of kilobytes.

 

Cascades Image does not offer this functionality. The solution is to download the image into a QImage, rather than an Image, do the physical resize, then convert the result into a Cascades ImageData, which can be loaded into an Image and used with an ImageView. Still with me so far?

 

Doing the conversion from QImage to ImageData is a bit of a pain, so I extended Qt::QImage to make a new class, QImageEx, which has a toNativeImage() member function to make the translation painless. This works well for me, but now I want to be able to create a new copy constructor for QImageEx that takes an Image parameter so I can do something like this:

 

bb::cascades::Image resize( int width, int height, bb::cascades::Image img ) {
   QImageEx thumbnail( img );
   
   return thumbnail.scaled( width, height ).toNativeImage();
}

Due to the wealth of things you can do to manipulate image with QImage and the dearth of such with Image, you can see how useful it would be to be able to convert back and forth at will.

 

Unfortunately, Image does not provide any access to the underlying image data, which could be manipulated into something that could be imported into a QImage. I know that image data is available somehow, since ImageView needs access to it to be able to display the image, but the interface used for this is just not published. Perhaps the Image and ImageView are C++ "friends". In any case, not making the image data inside an Image accessible is a dire design mistake, IMHO.

 

P.S. If I get this working I plan to release the QImageEx class for everyone to use. 



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.
Retired
PBernhardt
Posts: 749
Registered: ‎12-16-2008
My Device: BlackBerry Z30

Re: Convert bb::cascades::Image to QImage?

Well, the main reason you can't just pull the original byte array out of Image/ImageView is that it actually gets converted into an OpenGL texture as soon as you put it in.

 

It's obviously not ideal that Image and ImageView are so limited compared to QImage, but they are built using vastly different technologies under the hood. We definitely want to make things easier though, so if you have specific use cases, please log features in the Developer Issue Tracker: DIT

 

For your sprecifc problem, I think the only solution is to cache the data, either keeping it in memory or writing it to the file system.

Paul Bernhardt
Application Development Consultant
BlackBerry
@PBernhardt

Did this answer your question? Please accept this post as the solution.
Found a bug? Report it to the Developer Issue Tracker
Please use plain text.
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Convert bb::cascades::Image to QImage?

Thanks for the explanation Paul, but that still doesn't answer a very basic question... why can't we access the internal image bytes held by Image? No matter what format its in internally, it would be very helpful to be able to extract it from the Image object. 

 

I don't need to be able to get it in the original format of the ImageData used to create it, just a pointer to the texture would be fine since OpenGL textures can be applied to any "surface", even a flat one like a 2-dimensional bitmap. Alternately it would be nice if Image provided something like a .toBitmap() member function for obvious reasons.

 

As I said before, clearly ImageView can access the internal data somehow, or perhaps the Image "paints" the texture itself onto a canvas provided by ImageView. Either way, it should be possible to duplicate this in our own code if only we knew how the Image/ImageView partnership works.


PBernhardt wrote:

Well, the main reason you can't just pull the original byte array out of Image/ImageView is that it actually gets converted into an OpenGL texture as soon as you put it in.

 

It's obviously not ideal that Image and ImageView are so limited compared to QImage, but they are built using vastly different technologies under the hood. We definitely want to make things easier though, so if you have specific use cases, please log features in the Developer Issue Tracker: DIT

 

For your sprecifc problem, I think the only solution is to cache the data, either keeping it in memory or writing it to the file system.






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.
Retired
PBernhardt
Posts: 749
Registered: ‎12-16-2008
My Device: BlackBerry Z30

Re: Convert bb::cascades::Image to QImage?

I could only offer speculation as to why that function isn't available. There is probably some techincal reason that makes it difficult or awkward to provide access data (Cascades devs don't generally want OpenGL textures, for example).

 

As the platform matures, there is more opportunity to add specific features for more advanced or less common usage, so as I said, a feature request is the best bet :smileyhappy:

Paul Bernhardt
Application Development Consultant
BlackBerry
@PBernhardt

Did this answer your question? Please accept this post as the solution.
Found a bug? Report it to the Developer Issue Tracker
Please use plain text.
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Convert bb::cascades::Image to QImage?

Most likely nobody thought of it yet. LOL

 

I will indeed post this as a feature request.

 


PBernhardt wrote:

I could only offer speculation as to why that function isn't available. There is probably some techincal reason that makes it difficult or awkward to provide access data (Cascades devs don't generally want OpenGL textures, for example).

 

As the platform matures, there is more opportunity to add specific features for more advanced or less common usage, so as I said, a feature request is the best bet :smileyhappy:






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.