How to paint dots and lines in FMX (Android/iOS) without blur?

How to paint dots and lines in FMX (Android/iOS) without blur?
I tried a lot of samples in internet. Mainly what I need is to generate is a QRCode.
I found and tried to follow this: http://zarko-gajic.iz.hr/firemonkey-mobile-android-ios-qr-code-generation-using-delphi-xe-5-delphizxingqrcode/

But it won't work correctly as the image gets blurry. I don't know if my android phone is the guild because of its resolution, but anyway should exists some way to accomplish this.

In the article Zarko says to use low quality, I think I should use TCanvasQuality.HighPerformance but not works.
The image drawn gets out of scale and I also tried to adjust all the possible modes such fit, stretch, place, original... not working :(

Can someone help?
http://zarko-gajic.iz.hr/firemonkey-mobile-android-ios-qr-code-generation-using-delphi-xe-5-delphizxingqrcode/

Comments

  1. Set FMX Bitmap scale = Screen scale and size = initial size * Screen scale

    ReplyDelete
  2. Alexander Sviridenkov When you say do use the screen scale, you say to determine the mobile screen scale such ScreenService.GetScreenScale (FMX.Platform)? If it is other way I did not understand, sorry.

    ReplyDelete
  3. Yes, ScreenService.GetScreenScale. In FMX bitmaps are internally scaled by current screen scale, so to work with real pixels you should set Bitmap.Scale same as screen scale.

    ReplyDelete
  4. Ok, I will try it. As the bitmap is generated in runtime I need to test where exactly put the scale.

    ReplyDelete
  5. Magno Lima do you have a solution to image blare?

    ReplyDelete
  6. shlomo abuisak not yet, I am still trying, do you also think in using for mobile application?

    ReplyDelete
  7. Magno Lima Not yet. but may be centering the image and then resizing ?
    Centering give good result.

    ReplyDelete
  8. shlomo abuisak I've tried. So far nothing.

    ReplyDelete
  9. Magno Lima if you want to try this it is much better but one has to play with it.Return to paintbox

    procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
    var
    Scale: Double;
    begin
    // PaintBox1.Canvas.Brush.Color := clWhite;
    // PaintBox1.Canvas.FillRect(Rect(0, 0, PaintBox1.Width, PaintBox1.Height));
    if ((QRCodeBitmap.Width > 0) and (QRCodeBitmap.Height > 0)) then
    begin
    if (PaintBox1.Width < PaintBox1.Height) then
    begin
    Scale := PaintBox1.Width / QRCodeBitmap.Width;
    end else
    begin
    Scale := PaintBox1.Height / QRCodeBitmap.Height;
    end;
    PaintBox1.Canvas.DrawBitmap(QRCodeBitmap,Rect(0, 0, Trunc(Scale * QRCodeBitmap.Width), Trunc(Scale * QRCodeBitmap.Height)),Rect(0, 0, Trunc(Scale * PaintBox1.Width), Trunc(Scale * PaintBox1.Height)),100, true);
    end;

    ReplyDelete
  10. Magno Lima do not scale PaintBox1.Canvas.DrawBitmap(QRCodeBitmap,Rect(0, 0, Trunc({Scale *} QRCodeBitmap.Width), Trunc({Scale *} QRCodeBitmap.Height)),Rect(0, 0, Trunc({Scale *} PaintBox1.Width), Trunc({Scale * }PaintBox1.Height)),100, true);

    ReplyDelete
  11. It is not perfect but a starting point

    ReplyDelete
  12. Magno Lima in update i tried and it works OK so it is the
    unit FMX_DelphiZXingQRCode;

    Brush := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Black);
    Brush.Thickness := 2;
    QRCodeBitmap.SetSize(round(PaintBox1.Width),round( PaintBox1.Height));
    with QRCodeBitmap.Canvas do
    begin
    BeginScene();
    DrawLine(PointF(10, 10), PointF(100, 10), 1, Brush);
    EndScene;
    PaintBox1.Repaint;
    end;

    ReplyDelete
  13. shlomo abuisak Thank you! I will try it let you know. Shalom

    ReplyDelete
  14. Magno Lima I used Panagiotis comment on zarko-gajic.iz.hr - FireMonkey / Mobile (Android, iOS) QR Code Generation Using Delphi XE 5 / DelphiZXingQRCode
    and it works fine for me. Use "fit" for wrapmode.

    procedure TForm1.Update;
    const
    downsizeQuality: Integer = 2; // bigger value, better quality, slower rendering
    var
    QRCode: TDelphiZXingQRCode;
    Row, Column: Integer;
    pixelColor : TAlphaColor;
    vBitMapData : TBitmapData;
    pixelCount, y, x: Integer;
    columnPixel, rowPixel: Integer;
    function GetPixelCount(AWidth, AHeight: Single): Integer;
    begin
    if QRCode.Rows > 0 then
    Result := Trunc(Min(AWidth, AHeight)) div QRCode.Rows
    else
    Result := 0;
    end;
    begin
    QRCode := TDelphiZXingQRCode.Create;
    try
    QRCode.Data := Edit1.Text;
    QRCode.Encoding := TQRCodeEncoding(ComboBox1.ItemIndex);
    QRCode.QuietZone := StrToIntDef(Edit2.Text, 4);
    pixelCount := GetPixelCount(imgQRCode.Width, imgQRCode.Height);
    case imgQRCode.WrapMode of
    TImageWrapMode.iwOriginal,TImageWrapMode.iwTile,TImageWrapMode.iwCenter:
    begin
    if pixelCount > 0 then
    imgQRCode.Bitmap.SetSize(QRCode.Columns * pixelCount,
    QRCode.Rows * pixelCount);
    end;
    TImageWrapMode.iwFit:
    begin
    if pixelCount > 0 then
    begin
    imgQRCode.Bitmap.SetSize(QRCode.Columns * pixelCount * downsizeQuality,
    QRCode.Rows * pixelCount * downsizeQuality);
    pixelCount := pixelCount * downsizeQuality;
    end;
    end;
    TImageWrapMode.iwStretch:
    raise Exception.Create('Not a good idea to stretch the QR Code');
    end;
    if imgQRCode.Bitmap.Canvas.BeginScene then
    begin
    try
    imgQRCode.Bitmap.Canvas.Clear(TAlphaColors.White);
    if pixelCount > 0 then
    begin
    if imgQRCode.Bitmap.Map(TMapAccess.maWrite, vBitMapData) then
    begin
    try
    for Row := 0 to QRCode.Rows - 1 do
    begin
    for Column := 0 to QRCode.Columns - 1 do
    begin
    if (QRCode.IsBlack[Row, Column]) then
    pixelColor := TAlphaColors.Black
    else
    pixelColor := TAlphaColors.White;
    columnPixel := Column * pixelCount;
    rowPixel := Row * pixelCount;
    for x := 0 to pixelCount - 1 do
    for y := 0 to pixelCount - 1 do
    vBitMapData.SetPixel(columnPixel + x,
    rowPixel + y, pixelColor);
    end;
    end;
    finally
    imgQRCode.Bitmap.Unmap(vBitMapData);
    end;
    end;
    end;
    finally
    imgQRCode.Bitmap.Canvas.EndScene;
    end;
    end;
    finally
    QRCode.Free;
    end;
    end;

    ReplyDelete
  15. Now we have 2 options here, using TPaintBox or TImage... What is working with you now?

    ReplyDelete
  16. shlomo abuisak Perfect!!!! Perfect!!! It is working as it should!

    ReplyDelete

Post a Comment