1. Richard Donagrandi
  2. PowerBuilder
  3. Friday, 6 August 2021 17:44 PM UTC

Wondering if anyone has a solution to an issue I'm having...

I'm getting signature data from a pin pad in data-point format (not a bmp). I can graph this data using a graph datawindow and fill in the gaps to give the appearance of a solid line. The size (height and width) of the datawindow is something like 250 x 500. However when I use dw_1.Clipboard("gr_1"), the size of the image comes out to 1342 x 638, and the image gets distorted. 

Anyone know how to correct this? Can it be corrected?

Thanks,

John Fauss Accepted Answer Pending Moderation
  1. Friday, 6 August 2021 19:27 PM UTC
  2. PowerBuilder
  3. # 1

Hi, Richard - 

250 x 500 in what units? PowerBuilderUnits (PBU's)? Pixels? Width x Height? I assume the stated resultant image size of 1342 x 648 is in pixels, but it is impossible to tell with certainty from your question. Could you please clarify both sets of dimensions?

Comment
There are no comments made yet.
Richard Donagrandi Accepted Answer Pending Moderation
  1. Friday, 6 August 2021 19:56 PM UTC
  2. PowerBuilder
  3. # 2

Pixels... But the units are not important. It's about the proportions.

If my graph is 250 High x 500 Wide, the resulting image saved to the clipboard is 1342 High by 648 Wide, although the symbol used to plot the points is the same size either way, so this is definitely an issue with Powerbuilder improperly defining the page (image) size.

Changing the print page size of the graph object does not have any effect.

 

 

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Saturday, 7 August 2021 17:32 PM UTC
  2. PowerBuilder
  3. # 3

Since the Help for syntax 2 of the Clipboard PowerScript function contains no helpful information in this matter, and since the description of the action is very general (essentially "produces a bitmap of the graph"), and since the native graphing support in the DataWindow at best can be categorized as archaic and rudimentary, I'll go out on a limb and express my doubts that there is a way to improve the results.

I suggest you look at the "Bitmap" free code example at Roland Smith's terrific TopWizProgramming web site:

https://www.topwizprogramming.com/freecode_bitmap.html

I think with a little work, you could adapt the example code to be able to create a bit map of the DataWindow control containing the graph, as it uses Windows API functions to capture a snapshot of all or part of the desktop, window or a control.

Comment
There are no comments made yet.
Richard Donagrandi Accepted Answer Pending Moderation
  1. Tuesday, 10 August 2021 15:21 PM UTC
  2. PowerBuilder
  3. # 4

After reviewing the code at topwiz, I decided to construct the bmp myself from scratch...

A great description of the BMP file format can be found here: Bits to Bitmaps: A simple walkthrough of BMP Image Format | by Uday Hiwarale | System Failure | Medium

To do this, I initialize an array the same size as my signature data which would always be the same size, and all the points would already initialize to 0:

     int li_points[512,256]

I then set the points as I would a graph object. Since my BMP will be monochrome, I only have to set each point to 1. (Someone more ambitious could set each point to the integer (decimal) value of the pixel to represent the color.) Then finally convert everything to a byte array, then a blob:

ll_byte_count = 1
//CONSTRUCT HEADER

is_header= '424D3E400000000000003E00000028000000000200000001000001000100000000000000000000000000000000000000000000000000FFFFFF0000000000'
For li_n = 1 to LEN(is_header) step 2
    ls_testvalue = MID(is_header, li_n, 2)
    li_byte = of_hex_to_int(ls_testvalue)    // a simple routine that returns the decimal value from hex.
    lbyte_array[ll_byte_count] = byte(li_byte)
    ll_byte_count = ll_byte_count + 1
NEXT

ls_binary = ''


//My BMP is monochrome, so only one bit per pixel, but the pixel data still has to be stored by byte in the blob.
FOR li_rowY = 1 to 256
    FOR li_colX = 1 to 512
        
        li_testvalue = li_points[li_colX, li_rowY]

       //just-in-case
        if isNull(li_testvalue) or ( li_testvalue <> 1 and li_testvalue <> 0  ) then
            li_testvalue = 0
        end if
        ls_binary = ls_binary + String(li_testvalue)
        
        if Len(ls_binary) = 8 then
            li_byte = this.of_binary_to_int( ls_binary)  // a simple routine that returns the decimal value from a string that represents a binary number. e.g. '10010000'.
            lbyte_array[ll_byte_count] = byte(li_byte)
            ll_byte_count = ll_byte_count + 1
            ls_binary = ''
        end if

    NEXT
NEXT


//CONVERT INTO BLOB
a = lbyte_array
lblob_final = Blob(a)

//lbob_final should now be a properly constructed BMP

p_1.SetPicture ( lblob_final)

Comment
  1. John Fauss
  2. Tuesday, 10 August 2021 18:38 PM UTC
Thanks for sharing your solution, Richard!
  1. Helpful
  1. Armeen Mazda @Appeon
  2. Tuesday, 10 August 2021 19:28 PM UTC
Thanks for sharing!
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.