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/
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/
Set FMX Bitmap scale = Screen scale and size = initial size * Screen scale
ReplyDeleteAlexander 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.
ReplyDeleteYes, 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.
ReplyDeleteOk, I will try it. As the bitmap is generated in runtime I need to test where exactly put the scale.
ReplyDeleteMagno Lima do you have a solution to image blare?
ReplyDeleteshlomo abuisak not yet, I am still trying, do you also think in using for mobile application?
ReplyDeleteMagno Lima Not yet. but may be centering the image and then resizing ?
ReplyDeleteCentering give good result.
shlomo abuisak I've tried. So far nothing.
ReplyDeleteMagno Lima if you want to try this it is much better but one has to play with it.Return to paintbox
ReplyDeleteprocedure 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;
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);
ReplyDeleteIt is not perfect but a starting point
ReplyDeleteMagno Lima in update i tried and it works OK so it is the
ReplyDeleteunit 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;
shlomo abuisak Thank you! I will try it let you know. Shalom
ReplyDeleteMagno Lima I used Panagiotis comment on zarko-gajic.iz.hr - FireMonkey / Mobile (Android, iOS) QR Code Generation Using Delphi XE 5 / DelphiZXingQRCode
ReplyDeleteand 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;
Now we have 2 options here, using TPaintBox or TImage... What is working with you now?
ReplyDeleteMagno Lima Image
ReplyDeleteshlomo abuisak Perfect!!!! Perfect!!! It is working as it should!
ReplyDelete