Я пытаюсь создать своего рода редактор растровых изображений, поэтому я просто хочу нарисовать линию на растровом изображении без эффекта сглаживания в Firemonkey. Что-то вроде этого:
var
Bmp: TBitmap;
Bmp := TBitmap.Create(2000, 2000);
if (Bmp.Canvas.BeginScene) then
begin
Bmp.Canvas.Stroke.Color := TAlphaColors.Aquamarine;
Bmp.Canvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
Bmp.Canvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(Bmp);
Но это не работает. Я пытаюсь какое-то время с несколькими идеями, но безуспешно:
TImage с DisableInterpolation=true и даже GlobalUseGPUCanvas=False не работает.TPaintBox не соответствует нашим потребностям.Canvas.Quality=HighPerformance, но это свойство доступно только для чтения. Я пытался по-разному изменить растровое изображение Canvas.Quality, но ничего не вышло.Итак, как я могу просто нарисовать линию без эффекта сглаживания в Firemonkey?
PS: я использую Delphi 10.2.3 (Токио)





FireMonkey рисует линии на сетке между пикселями, а не на пикселях. Итак, вам нужно добавить 0,5 к каждой координате, чтобы нарисовать пиксели:
Bmp.Canvas.DrawLine(PointF(5.5, 5.5), PointF(100.5, 100.5), 1);
Это не отключает сглаживание, но позволяет избежать чрезмерного сглаживания, которое происходит в противном случае. Мне неизвестна функция FireMonkey, отключающая сглаживание. Вам нужно будет вызвать собственную функцию ОС, например CGContextSetAllowsAntialiasing в MacOS, но обычно она больше не нужна, как только вы поймете, как рисовать на пикселях.
Наконец я нашел способ сделать это. Это настолько просто, что мне интересно, есть ли в растворе какой-то скрытый яд (LOL). TCanvasManager позволяет создавать HighPerformance Canvas из заданного растрового изображения. По моим тестам, рисует без антиалиасинга. Вот код:
var
Bmp: TBitmap;
TmpCanvas: TCanvas;
begin
Bmp := TBitmap.Create(2000, 2000);
TmpCanvas := TCanvasManager.CreateFromBitmap(Bmp, TCanvasQuality.HighPerformance);
if (TmpCanvas.BeginScene) then
begin
TmpCanvas.Stroke.Color := TAlphaColors.Aquamarine;
TmpCanvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
TmpCanvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(TmpCanvas);
FreeAndNil(Bmp);
Я также обнаружил, что он не работает с методом записи текста на холсте (Canvas.FillText).
Я надеюсь, что это поможет многим другим с той же проблемой.