Kattes Posted July 11, 2021 Share Posted July 11, 2021 First of all, I would like to apologize for the somewhat lurid headline, but what happened to me yesterday made me doubt my more than 35 years of experience as a programmer. But first things first, what happened? I was programming a registration application for a local event organizer for his guests. Basically a very simple application that collects people's personal information, writes it into a database and then generates a QR code to be displayed on the mobile device and later scanned upon entry. To make sure that the code used for registration is unique, a 6-digit alpha string is generated and checked again with the database for uniqueness. All this works without any problems. The generated string is also displayed correctly on the mobile devices, but then something completely crazy happens when the string is converted into a QR code. Because here it sometimes happens that the content of the QR code does not match the displayed string content. But it is not the case that some nonsense is then generated, it is a QR code with the identical content from another session! It is simply not clear to me how this can happen. No global variables / or object instances are used and the code for generating the QR code also looks completely inconspicuous. I would be very grateful for any ideas and suggestions, because you can imagine what happens when two people with identical QR codes suddenly appear at the entrance.... Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 Attached you will find the QRCode unit used and below, how it is used. procedure TuFrameDetails.UnimFormCreate(Sender: TObject); var QRCodeBitmap : tBitmap; sQR : string; begin with UniMainModule do begin bSkip := true; sQR := sUserId + '-999999-'+ sTransRef; UnimLabelRef.Caption := sQR; try QRCodeBitmap := CreateQRCode(sQR); ResizeBitmap(QRCodeBitmap,8); UnimImageQR.Picture.Bitmap.Assign(QRCodeBitmap); QRCodeBitmap.Free; finally bSkip := false; end; end; end; function TuFrameDetails.CreateQRCode(qrTxt: string): tBitmap; var QRCode: TDelphiZXingQRCode; Row, Column: Integer; begin QRCode := TDelphiZXingQRCode.Create; result := tBitmap.Create; try QRCode.Data := qrTxt; QRCode.Encoding := qrAuto; QRCode.QuietZone := 4; result.SetSize(QRCode.Rows, QRCode.Columns); for Row := 0 to QRCode.Rows - 1 do begin for Column := 0 to QRCode.Columns - 1 do begin if (QRCode.IsBlack[Row, Column]) then begin result.Canvas.Pixels[Column, Row] := rgb(0,0,32); end else begin result.Canvas.Pixels[Column, Row] := clWhite; end; end; end; finally QRCode.Free; end; end; procedure TuFrameDetails.ResizeBitmap(var Bmp: tBitmap; Scale: double); var BmpTemp: tBitmap; begin BmpTemp := TBitmap.create; BmpTemp.PixelFormat := Bmp.PixelFormat; BmpTemp.Width := trunc(Bmp.Width * Scale); BmpTemp.Height := trunc(Bmp.Height * Scale); BmpTemp.Canvas.StretchDraw(Rect(0,0,BmpTemp.Width, BmpTemp.Height), Bmp); Bmp.Free; Bmp := BmpTemp; end; QRCode.zip Quote Link to comment Share on other sites More sharing options...
mierlp Posted July 11, 2021 Share Posted July 11, 2021 hi I have a event management system for events en festival is also create invites with qr-code but without any problem What i do is when a user is added to the database i create a 19 digit unique 'barcode' number based on date+date...till milliseconds and the number is stored in the database....you need it for scanning. you can do it on the OnNewRecord event of OnBeforePost What i see from you code is that you created on the UnimFormCreate and possibe the same values are use for creating the qrcode number. I use fastreport to to create the qrcode imge...i have a report with the format off a general phone screen. Now can I set up other information besides the qr code like event name and entrance location and date/time Quote Link to comment Share on other sites More sharing options...
Oliver Morsch Posted July 11, 2021 Share Posted July 11, 2021 TBitmap is not Thread safe. So you must be sure that only one Session uses it at the same Moment Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 Some more from my research... procedure TuFrameDetails.UnimPanelSellMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i,w,h : integer; s : string; QRCodeBitmap : tBitmap; begin Randomize; s := '123456'; for i := 1 to length(s) do s[i] := Chr(Ord('A')+ Random(26)); with UniMainModule do begin sQR := sUserId + '-999999-'+ s; UnimLabelRef.Caption := sQR; QRCodeBitmap := CreateQRCode(sQR); try UnimImage1.Picture.Bitmap.Assign(QRCodeBitmap); // fits to string sQR from content 100% - but too small, so needs to be scaled to avoid antializing w := QRCodeBitmap.Width * 8; h := QRCodeBitmap.Height * 8; UnimImageQR.Picture.Bitmap.Width := w; UnimImageQR.Picture.Bitmap.Height := h; UnimImageQR.Picture.Bitmap.Canvas.StretchDraw(Rect(0,0,w,h), QRCodeBitmap); // looks sharp, but content is not always in line with string sQR finally QRCodeBitmap.Free; end; end; end; So the problem happens if I try to use Strechdraw to the UnimImage bitmap. Also assigning a stretched bitmap does not work reliable. So in summary the content of UnumImage1 and UnimImageQR is sometimes (next to their size, which is obvious) different. In such a case UnimImageQR shows something what happend in the past. I am using only one active browser window. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 11, 2021 Share Posted July 11, 2021 3 hours ago, Kattes said: sUserId + '-999999-'+ sTransRef; How do you set values for sUserId and sTransRef, is this an automatic generating function? Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 UserId is the record ID of the new created user record coming from the database and sTransferRef is randomly created 6 character string (as you can see from my last post - here the variable is called "s"). But the problem is coming from UnimImage component. It seems to load content coming from somewhere sometimes ?!?!? Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 11, 2021 Share Posted July 11, 2021 So, if you ignore the automatically generated code (just use static), do you get the same problem ? in witch part of string is differens in QR code, on sUserId or sTransferRef ? Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 if a deviation is happening, it will happen in both parts of the string so sUserId AND sTransferRef. This is so crazy, so I think I will make a test case for everybody, who is interesting in this case. Further news from my tests: If I increase the bitmap zoom factor from 8 to e.g. 80 the effect seams to go away ! Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 Attached you will find the simplified test-case. I have thrown out everything what is not needed. For testing the behavior you will need two running instances of the web-application. Best is to run it in two different Browser Windows. Click Refresh and a new QR-Code will generated. The sharp one is zoomed by factor 8. Once you have clicked refresh some times in the first browser window switch to the second one and click refresh here as long as you cannot see a difference in the QR-pattern. Sometimes it will take a while but I am pretty sure that you will see the effect, too. TestCase.zip Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 11, 2021 Share Posted July 11, 2021 1 hour ago, Kattes said: TestCase.zip 6.97 MB · 1 download Hello, Sorry, do you mean that this string is sometimes not unique?: sQR := sUserId + '-999999-'+ s; Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 11, 2021 Author Share Posted July 11, 2021 Sorry if I didn't make it clear. I will try to describe the effect again based on the testcase I created. If you open the source code you will see that there is only one method, which is responsible to create a string, which then will be used to create a QR-Code bitmap using an external library. The content of the String is also assigned to a Label to make it visible. First part of the string is constant during a session and the last part varies with every mouse click on the refresh label. The generated QR-Code bitmap will be assigned to two different unimImages. The first Image get the content of the QR-Code bitmap directly via : UnimImage1.Picture.Bitmap.Assign(QRCodeBitmap); The second UnimImage gets the content of the same QR-Code Bitmap via StretchDraw: w := QRCodeBitmap.Width * 8; h := QRCodeBitmap.Height * 8; UnimImageQR.Picture.Bitmap.Width := w; UnimImageQR.Picture.Bitmap.Height := h; UnimImageQR.Picture.Bitmap.Canvas.StretchDraw(Rect(0,0,w,h), QRCodeBitmap); So everybody now would think that next to the zoom level both images will look equal, but for whatever reason this is sometimes NOT the case. If this happens the content of UnimImageQR is not something totally stupid, because if you scan the code with a QR-Scanner App its content string is something which was created before from a totally different session. So all this is totally unlogic and crazy, but it happens! For whatever reason the zoom factor also plays a role here. A higher value than 8 seems to minimize the risk of this effect - don't ask me why. As some kind of a hotfix I am now using a zoom factor of 80 and only can pray that if the next event comes up it will not end in chaos again, with hundreds of visitors with doubled QR-Codes. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 12, 2021 Share Posted July 12, 2021 can you try using qr code generated via goolge, and just download and load image ? "https://chart.apis.google.com/chart?chs=400x400&cht=qr&chld=M&chl=YOURQRSTRINGHERE" Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 12, 2021 Share Posted July 12, 2021 I was googling and here is the first link found: https://davidshimjs.github.io/qrcodejs/ This JS library can also be used to generate QR code I think. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 12, 2021 Share Posted July 12, 2021 @Sherzod Yes, I suggest for test purposes only to download image with QR code. I suggested using a different application to generate a QR code image and just drawing to check the problem. If the problem still exists, then the drawing procedure is a problem. Quote Link to comment Share on other sites More sharing options...
Marlon Nardi Posted July 12, 2021 Share Posted July 12, 2021 You may also be using this QrCode component of mine for testing. It is completely Free and with full source code. https://store.falconsistemas.com.br/?filter=fsqrcode 3 Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 12, 2021 Author Share Posted July 12, 2021 Hi guys, I really appreciate your help and support. It shows me again how important it is to have an active community of people willing to help. Ultimately though, the QR code library is not the problem here. The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 . Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 12, 2021 Share Posted July 12, 2021 4 minutes ago, Kattes said: Ultimately though, the QR code library is not the problem here. Yes you are right. 5 minutes ago, Kattes said: The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 . I was not able to reproduce the issue. Sorry, maybe I didn't test well. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 12, 2021 Share Posted July 12, 2021 7 minutes ago, Kattes said: Hi guys, I really appreciate your help and support. It shows me again how important it is to have an active community of people willing to help. Ultimately though, the QR code library is not the problem here. The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 . Hello, can You try to : 1. create QRCode 2. Save to local File with name (QRDateTimeMiliseconds) 3. Load from file into image to show on end User Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 12, 2021 Author Share Posted July 12, 2021 23 minutes ago, irigsoft said: Hello, can You try to : 1. create QRCode 2. Save to local File with name (QRDateTimeMiliseconds) 3. Load from file into image to show on end User I had a similar idea, but to work with a MemoryStream instead of a file. Unfortunately, all these tests are very time-consuming and at the end I still don't know if the problem has really been solved or if I just didn't do enough tests to find the error. Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 12, 2021 Author Share Posted July 12, 2021 1 hour ago, Sherzod said: Yes you are right. I was not able to reproduce the issue. Sorry, maybe I didn't test well. Have you tried my compiled exe or did you build a new one? Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 12, 2021 Share Posted July 12, 2021 2 minutes ago, Kattes said: Have you tried my compiled exe or did you build a new one? I compiled a new one. Quote Link to comment Share on other sites More sharing options...
Kattes Posted July 12, 2021 Author Share Posted July 12, 2021 2 minutes ago, Sherzod said: I compiled a new one. Can you try my exe, please? Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 12, 2021 Share Posted July 12, 2021 I was able to reproduce... Quote Link to comment Share on other sites More sharing options...
Sherzod Posted July 12, 2021 Share Posted July 12, 2021 Did you mean this? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.