Я просто хочу нарисовать вертикальную пунктирную толстую линию на слое в ImgView32. Я также хочу, чтобы моя линия была толще, поэтому я рисую несколько линий близко друг к другу, потому что Canvas.Pen.Width не влияет на методы LineTo. Итак, мой код выглядит следующим образом:
procedure TMainForm.PaintDottedHandler(Sender: TObject;Buffer: TBitmap32);
var
Cx, Cy,raza: Single;
W2, H2: Single;
I,J: Integer;
points:TArrayOfFloatPoint;
Center, Radius:TFloatPoint;
const
CScale = 1 / 200;
begin
if Sender is TPositionedLayer then
with TPositionedLayer(Sender).GetAdjustedLocation do
begin
W2 := (Right - Left) * 0.5;
H2 := (Bottom - Top) * 0.5;
Cx := Left + W2;
Cy := Top + H2;
W2 := W2 * CScale;
H2 := H2 * CScale;
Buffer.PenColor := clRed32;
Buffer.MoveToF(Cx-2,Top);
Buffer.LineToFSP(Cx-2 , Bottom);
Buffer.MoveToF(Cx-1,Top);
Buffer.LineToFSP(Cx-1 , Bottom);
Buffer.MoveToF(Cx,Top);
Buffer.LineToFSP(Cx , Bottom);
Buffer.MoveToF(Cx+1,Top);
Buffer.LineToFSP(Cx+1 , Bottom);
Buffer.MoveToF(Cx+2,Top);
Buffer.LineToFSP(Cx+2 , Bottom);
end;
end;
Таким образом, линия предназначена для размещения в середине нового слоя. Я добавляю слой, используя это:
procedure TMainForm.DottedLine1Click(Sender: TObject);
var
L: TPositionedLayer;
begin
L := CreatePositionedLayer;
L.OnPaint := PaintDottedHandler;
L.Tag := 2;
Selection := L;
end;
Для остальной части кода просто добавьте мой код в пример слоев, и вы сможете воспроизвести мою проблему.
Насколько я читал, для рисования пунктирной линии существует несколько подходов, таких как Stipple с LineToFSP (используется в моем коде) или PolyPolygonFS с точками BuildDashedLine. Но я не могу заставить ни один из них работать правильно. На самом деле второй подход ничего не делает... поэтому я придерживаюсь первого подхода. Таким образом, кажется, что каждый раз, когда он начинает рисовать линию, случайным образом начинается пунктирная линия. Так что либо пиксель, либо пустой. Поэтому, когда я изменяю размер слоя, линия трансформируется, как показано на следующих изображениях:
И на самом деле все, чего я хочу добиться, это:
И, конечно же, я хочу, чтобы линия снова рисовалась при изменении размера слоя, не искажая его (поэтому я использую подход обработчика onPaint). Если я просто нарисую простую линию на слое (используя Bitmap.Canvas), а затем изменю размер слоя, то линия будет искажена, как при растяжении jpeg, поэтому я хочу этого избежать.
Итак, подскажите, пожалуйста, как нарисовать толстую пунктирную линию на слое в ImgView32 (TGraphics32)
ИЗМЕНИТЬ
Попробовав код из ответов, я заставил его работать. Однако у этого слоя есть побочный эффект: при изменении размера слоя (с помощью мыши) при некоторой ширине цвет пунктирной линии тускнеет и размывается, как показано ниже:
Перед изменением размера После изменения размера (иногда).
Вы можете воспроизвести это самостоятельно, используя тот же код.
ИЗМЕНИТЬ
Есть еще одна проблема с этим специальным слоем: сохранение его в файл... Я пытался сохранить его как прозрачный PNG, используя 2 подхода, но я продолжаю получать поврежденный файл. Даже если я попытаюсь сохранить слой как растровое изображение, произойдет то же повреждение. Пожалуйста, проверьте и этот вопрос:
with TLine32.Create do try dashes := MakeArrayOfFloat([3, 3]); EndStyle := esClosed; SetPoints([FixedPoint(Cx-2,Top), FixedPoint(Cx-2,Bottom)]); Draw(Buffer, 3, dashes, clBlack32, clBlack32);
- person user1137313   schedule 17.04.2015