Beijer Electronics (formerly QSI Corporation)

Manufacturer of Mobile Data and Human Machine Interface Terminals.
It is currently Mon Nov 20, 2017 12:50 am

All times are UTC - 7 hours




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: Dynamic Bitmaps
PostPosted: Thu Oct 23, 2008 1:13 pm 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
OK, through the search I found these two threads:

viewtopic.php?f=6&t=1540&p=2282&hilit=bitmap#p2282
viewtopic.php?f=6&t=3674&p=4761&hilit=bitmap#p4761

related to this exact topic. I have downloaded the Bitmap_DisplayG70.zip and run both the server.exe and the bitmapdisplay.qly file. They appear to connect but I can't figure out how to get anything sent between the two. And I can't get the server.exe source to compile in VS .Net 2005.

I'm thinking though that my problem may be a bit less complex; I'd like to simply transfer a file on command to the G70 and then tell it what file to look for on the flash storage. It would be a one time deal as the file would only need to be sent to the G70 one time, unless updates were necessary. Essentially we want to have a dynamic "header" bitmap based on the user logged into the G70. So the process would be something like:

On the server where our system is based, create a User, add the user's bitmap and send it to all the units. When the user logs in to any G70 they see their bitmap because the server will tell the G70 which bitmap to display.

Is the Bitmap_DisplayG70.zip way the easiest way to accomplish this?
Thanks for the help.
Doug


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Thu Oct 23, 2008 1:40 pm 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Well, the simplest solution would probably be to use FTP to download the file to the G70. Just include an FTP server object in your workspace and you are ready to receive files via FTP.

Your bigger challenge would be to get the image into the Qlarity pixmap format. This could be done either on the host which sends the image or on the Qlarity terminal (assuming you are using .bmp images), but is more easily done on the host side.

It is somewhat ironic that you ask this question right now, as last weekend, I spent a couple of hours writing code to turn a spare G75 on my desk into a digital picture frame, with a server program on my PC which sends a new random photo from a directory on my PC to the G75 every minute.

I would offer to send you this code, but I suspect it is way beyond what you need (it uses some advanced graphics libraries to determine an optimal palette as well as rotating and scaling the original image).

For what you are describing, I would write a PC server app that takes a graphics file and converts it to a pixmap (I use the free CxImage library for this in C++), then use FTP to send the file over. On the terminal side, I would probably transfer the new file to a specific, known name. Once a minute or so I would have the terminal check to see if the file had arrived and if so, would load it and copy it to a new location. I would then delete the FTP transferred file so I could detect when the next one arrived.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Fri Oct 24, 2008 7:07 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
Jeremy wrote:
Your bigger challenge would be to get the image into the Qlarity pixmap format. This could be done either on the host which sends the image or on the Qlarity terminal (assuming you are using .bmp images), but is more easily done on the host side.


That's what I was trying to learn how to do with the Server.exe app in the zip file. However, it's been over a decade since I last touched C++, and the app wouldn't compile. Is it possible to do this in C#?


Jeremy wrote:
It is somewhat ironic that you ask this question right now, as last weekend, I spent a couple of hours writing code to turn a spare G75 on my desk into a digital picture frame, with a server program on my PC which sends a new random photo from a directory on my PC to the G75 every minute.

Thats an expensive digital picture frame :wink:

Jeremy wrote:
For what you are describing, I would write a PC server app that takes a graphics file and converts it to a pixmap (I use the free CxImage library for this in C++), then use FTP to send the file over. On the terminal side, I would probably transfer the new file to a specific, known name. Once a minute or so I would have the terminal check to see if the file had arrived and if so, would load it and copy it to a new location. I would then delete the FTP transferred file so I could detect when the next one arrived.


I'd like to be able to do this in C# if at all possible; our current apps are all C#.


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Fri Oct 24, 2008 7:37 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
C# is not the problem per se (my examples are all C++ because that is the language, aside from Qlarity, that I know best).

In terms of Pseudo Code, here is the basic idea of how to convert an image to a pixmap:
Code:
dim pixmapBuf[4 + image.width * image.height] as byte
// Write the width to the first 2 bytes of the buffer
// Write the height to the next 2 bytes
// little endian is a little more convient
pixmapBuf[0] = image.width % 256
pixmapBuf[1] = image.width / 256
pixmapBuf[2] = image.height % 256
pixmapBuf[3] = image.height / 256

//Loop through and fill in the pixels
//This assumes that the r, g and b values of the pixmap are 8 bit integers
dim index as integer
index = 4
for y = 0 to image.height -1
   for x = 0 to image.width -1
      Pixel pix= image.GetPixel(x, y)
      r = (pix.r >> 5) // Get the 3 most significant bits of red
      g = (pix.g >> 5) // Get the 3 most significant bits of green
      b = (pix.b >> 6) // Get the 2 most significant bits of blue
      // now convert the r,g & b to an 8 bit integer
      pixmapBuf[index] = (r << 5) | (g << 2) | b
   next
next

WriteToFTPLocation(pixmapBuf, "/NewQlarityImage.pix")





Here is some sample Qlarity code. It assumes you hijack a labelV2 to do the actual drawing
Code:
'Qlarity Global Code
' Now on the qlarity side, you could parse this as follows
' error handling omitted for bervity
dim pix[] as byte
func ParsePixmap()
    dim desc as filedesc
    dim w, h as unibyte

    desc = OpenFile ("/NewQlarityImage.pix", FILE_READ AND FILE_BINARY)
    SetFilePos(desc, -1, true)
    redim(pix, GetFilePos(desc)-4)
    SetFilePos(desc, 0, true)

    ReadFile(desc, w)
    ReadFile(desc, h)
    ReadFile(desc, pix)

    label_1.width = w
    label_1.height = h
endfunc


'In Label_1
func Draw()
    handles MSG_DRAW

    DrawPixmap(xPos, yPos, pix, width, height)
endfunc



_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Fri Oct 24, 2008 7:40 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
This is great. Thanks for the help. I'll post back when I get it working.


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Mon Dec 01, 2008 3:14 pm 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
Hey Jeremy,

I've got this working somewhat, but I'm getting an error from an internal call:
Quote:
Exception 134: SetObjProp: Unable to find property by name (severity: 5) ( in library --basic: necessary line 150)


Coming from the following line:
Code:
            SetObjProp(parentPath[i], "activetab", str(parentPath[i+1]))


Any ideas as I'm lost here.

BTW, with respect to your BMP to Pixmap convert code, I had to add an increment on the Index variable. I believe this is correct although I haven't yet been able to display the pixmap on the unit yet.

Thanks
Doug


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Mon Dec 01, 2008 3:21 pm 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Not surprised that you had to add an increment -- it was pseudo code and not anything I had tested.

Code:
 SetObjProp(parentPath[i], "activetab", str(parentPath[i+1]))


I am not sure what you are trying to accomplish here. If I had to take a guess, I would say that parentPath[i] for whatever i you are using is not a TabContainer object, which is the only object that I know of that has an activetab property.

I am also not really sure what parentPath is supposed to represent.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Mon Dec 01, 2008 5:48 pm 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
Sorry I think this is because I wasn't calling "ParsePixmap" first. I was tired yesterday :D


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 7:39 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
OK, thanks for the help. I've got it working but it's a tad touchy. If the label is visible on app startup I get that weird error I mentioned above. Also, if I'm working in Foundry and simply open the "eye" to display the label I get that error as well. It's coming from _ShowScreen. My guess is I need some error handling on the Draw function.


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 7:49 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Are you switching screens during a draw? That won't work and will cause an exception.

Are you using a beta QF and do you have Extra Exception Tracking enabled? (Tools->Settings->Compiler). If so try disabling and see if that fixes the problem. If this latter one is the case, we should have it fixed in the latest beta build.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 9:09 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
On the startup, there very well could be a _showscreen call from elsewhere in the app in the middle of the draw. Not sure how I would go about preventing it; is there a way to know when the label is drawing?

As for the second part, no, not using a beta, and I don't have an Extra Exception Tracking option in my enabled warnings box (I'm running foundry v2.50). I enclosed the drawpixmap call in a check error block and the error no longer appears when switching to Layout View with the label visible. I assume it's using the draw func to display the label even in Layout View.

I think with exception handling I can work around these minor issues.


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 9:15 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Well, on the assumption that the problem is a call to _showscreen in the middle of a Draw, you might want to track that down.

There is no API you can call along the lines of IsDrawing(). Actually I have never really needed it -- normally I just don't do object management during a draw. If you want to track down the problem, (mostly to see if you have a design issue), I would suggest you get the latest beta of QF. (www.qsicorp.com/engfiles, under bleeding_edge). The 2.60 beta, when in Simulation View, will automatically break on unhandled exception so that you can examine the call stack.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 10:27 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
You might like this.

Rather than download the new version, I just searched for all instances of calls to showscreen and breakpointed them.

Well, I have an Exception Display (ExceptionDisplayV2) that will show a message to the user when there's an unhandled exception (which was because the DrawPixmap call was not inside a CheckError block). It calls my function "DoError" which does a show screen to show my custom error screen to the user. Is this bad design? Would there be a better way to show the error?


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 10:34 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
How are you calling your DoError function from the ExceptionDisplay object? The OnExceptionCaught event will never fire in the context of a draw message.

Are you overriding the ExceptionDisplay's Draw function for some reason?

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
 Post subject: Re: Dynamic Bitmaps
PostPosted: Tue Dec 02, 2008 10:44 am 
Offline
User avatar

Joined: Mon Apr 09, 2007 10:50 am
Posts: 48
Location: Dayton, Ohio
Jeremy wrote:
How are you calling your DoError function from the ExceptionDisplay object? The OnExceptionCaught event will never fire in the context of a draw message.

Are you overriding the ExceptionDisplay's Draw function for some reason?


Here's the exact code in the OnExceptionCaught.

Code:
func OnExceptionCaught(errstr as string, errtype as unibyte, errlevel as unibyte)
    DoError("Error: " + errstr + "\r\n")
    _ClearException()
endfunc


It does appear to be firing from the Label's Draw event as that's the only Draw function I'm overriding.

DoError parses the passed string and displays an error screen with the _ShowScreen call. Main thing to take away from this is ALWAYS have exception handling when overriding events.

I commented out the code in the ExceptionCaught event. Now, I get the DrawPixmap: invalid size error instead of the weird show screen error. This error is because the ParsePixmap hasn't been called yet. I think as long as I have the call to DrawPixmap in a Check Error block I'll be OK.

Or I should probably check the status of the pix byte array and see if it's been intialized.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 7 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group