2017-01-13 2 views
1

델파이 2007에서 원형 진행률 막대를 개발해야하는데 제 3 자 구성 요소 (회사 정책)를 사용할 수 없습니다. Canvas를 사용하여 호를 그립니다. 정상적으로 작동하지만 이미지의 해상도가 매우 낮습니다. 캔버스 드로잉의 해상도를 향상시킬 수 있습니까?델파이 : 고해상도 아크 그리기

코드 샘플 :

procedure TForm1.DrawPieSlice(const Canvas: TCanvas; const Center: TPoint; 
    const Radius: Integer; const StartDegrees, StopDegrees: Double); 
//Get it in http://delphidabbler.com/tips/148 
const 
    Offset = 90; 
var 
    X1, X2, X3, X4: Integer; 
    Y1, Y2, Y3, Y4: Integer; 
begin 
    X1 := Center.X - Radius; 
    Y1 := Center.Y - Radius; 
    X2 := Center.X + Radius; 
    Y2 := Center.Y + Radius; 
    X4 := Center.X + Round(Radius * Cos(DegToRad(Offset + StartDegrees))); 
    Y4 := Center.y - Round(Radius * Sin(DegToRad(Offset + StartDegrees))); 
    X3 := Center.X + Round(Radius * Cos(DegToRad(Offset + StopDegrees))); 
    Y3 := Center.y - Round(Radius * Sin(DegToRad(Offset + StopDegrees))); 
    Canvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4); 
end; 

procedure TForm1.SpinEdit1Change(Sender: TObject); 
var 
    Center: TPoint; 
    Bitmap: TBitmap; 
    Radius: Integer; 
    p: Pointer; 
begin 
    Label1.Caption:= SpinEdit1.Text+'%'; 
    Bitmap := TBitmap.Create; 
    try 
    Bitmap.Width := Image1.Width; 
    Bitmap.Height := Image1.Height; 
    Bitmap.PixelFormat := pf24bit; 
    Bitmap.HandleType := bmDIB; 
    Bitmap.ignorepalette := true; 
    Bitmap.Canvas.Brush.Color := clBlack; 
    Bitmap.Canvas.Pen.Color := clHighlight; 
    Bitmap.Canvas.Pen.Width := 10; 
    Center := Point(Bitmap.Width div 2, Bitmap.Height div 2); 
    Radius := 61; 
    DrawPieSlice(Bitmap.Canvas, Center, Radius,0,round(SpinEdit1.Value * -3.6)); 

    Image1.Picture.Graphic := Bitmap; 
    finally 
    Bitmap.Free; 
    end; 
end; 

결과 :

Sample

내가 다른 솔루션을위한 제안에 열려입니다.

+2

해상도는 사용자가 결정합니다. 해상도를 더 높이려면 원을 더 크게 만듭니다. 정말로 당신이 안티 앨리어싱을 원한다면 현실적으로 graphics32 또는 gdi +로 전환해야합니다. 회사 내부 정책에 위배되는 경우에는 직접 앤티 앨리어싱을 작성하는 방법을 배워야합니다. –

답변

6

안티 앨리어싱 가능성이있는 타사 그래픽 라이브러리를 사용할 수없는 경우 Windows에 포함 된 GDI +를 사용하는 것이 좋으며 Delphi에는 래퍼가 포함되어 있습니다.

uses 
    ..., GDIPAPI, GDIPOBJ, GDIPUTIL //included in Delphi standard modules 

var 
    graphics: TGPGraphics; 
    SolidPen: TGPPen; 
begin 
    graphics := TGPGraphics.Create(Canvas.Handle); 
    graphics.SetSmoothingMode(SmoothingModeAntiAlias); 
    SolidPen := TGPPen.Create(MakeColor(255, 0, 0, 255), 31); 
    SolidPen.SetStartCap(LineCapRound); 
    SolidPen.SetEndCap(LineCapRound); 
    graphics.DrawArc(SolidPen, 100, 100, 100, 100, 0, 270); 
    graphics.Free; 
    SolidPen.Free; 

enter image description here

0

아주 간단한 해결책이 임시 비트 맵에 더 높은 해상도 (같은 1.5 배 또는 2 배)에서 당신의 원을 그린 다음 (당신의 해상도로 크기를 조정하는 것은 크기 조정 과정이 있기 때문에 원에 앤티 앨리어싱 추가) 마지막으로이 비트 맵을 캔버스에 직접 그립니다. 실제로 이것은 많은 알고리즘이 안티 알리아스를 추가하는 것과 같습니다.

+0

나는 그렇게 생각하지 않는다. 적어도 표준 델파이 비트 맵은 크기 변경시 별칭이 아닙니다. 그리고 나는 이것이 안티 앨리어싱에 적절한 방법이라고 천천히 믿지 않습니다. –

+1

@DavidHeffernan SetStretchBltMode (DC, HALFTONE)를 호출하면이 기능이 작동합니다. – EugeneK

+0

잘 모르겠습니다. –

0

Direct2D 유닛이 Delphi 2007에 이미 있는지는 잘 모르겠지만 CPU가 아닌 GPU를 사용하여 렌더링되기 때문에 Direct2D를 사용하는 것이 더 좋은 옵션 일 수 있습니다.

uses Vcl.Direct2D, Winapi.D2D1; 

... 

var 
    D2DCanvas: TDirect2DCanvas; 
begin 
    if TDirect2DCanvas.Supported then 
    begin 
    D2DCanvas := TDirect2DCanvas.Create(PaintBox.Canvas, PaintBox.ClientRect); 
    try 
     D2DCanvas.RenderTarget.BeginDraw; 
     D2DCanvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); 
     D2DCanvas.Pen.Color := TColors.Blue; 
     D2DCanvas.Pen.Width := 10; 
     D2DCanvas.Arc(100, 100, 200, 200, 100, 150, 150, 100); 
     D2DCanvas.RenderTarget.EndDraw; 
    finally 
     D2DCanvas.Free; 
    end; 
    end 
end;