Перейти к содержанию
  • Регистрация
  • 0
ODmitrijS

Алгоритм заливки замкнутой области рисунка

Вопрос

Подскажите алгоритм или готовый пример заливки замкнутой области рисунка произвольной формы определенным цветом?
Моё решение часто приводит к переполнению стека.

Изменено пользователем ODmitrijS

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендуемые сообщения

  • 0

Вопрос точнее ставьте, используете функции Pascal для заливки цветом или нужно написать алгоритм заливки?

Если первое, то выкладывайте код; если второе - то описание алгоритма и код... 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Полагаю это поможет: https://habrahabr.ru/post/116398/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Интересуют любые варианты.
Использую XE10

Мой вариант. Можно конечно подумать, только вероятно всё придумано до меня:

procedure TForm1.fill(x,y: integer);
begin
  if bitdata1.GetPixel(x,y)=TAlphacolors.white then bitdata1.SetPixel(x,y,Talphacolors.Red);
  if bitdata1.GetPixel(x+1,y) = TAlphacolors.White then
    fill(x+1,y);
  if bitdata1.GetPixel(x-1,y) = TAlphacolors.White then
    fill(x-1,y);
  if bitdata1.GetPixel(x,y+1) = TAlphacolors.White then
    fill(x,y+1);
  if bitdata1.GetPixel(x,y-1) = TAlphacolors.White then
    fill(x,y-1);
end;

 

Изменено пользователем Brovin Yaroslav

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

ой-ё... рекурсия, метод лесного пожара, емнип.

Не, если нельзя ограничить глубину вложенности - само собой можно схватить преполнение стека.

понятно, что всё придумано до нас, но если изобретать велосипеды - я бы завел список из TPoint с невозможностью добавления дубликатов (например - TDictionary) и проходил бы по нему вашим алгоритмом, но вместо рекурсивного вызова - добавление точек в список. Точки, закрашиваемые красным - удаляются из списка. Если на очередном проходе списка количество элементов  = 0 - мы обошли всю фигуру.

Изменено пользователем kami

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От Zyablik3000
      Здравствуйте!
      Есть самописный компонент - индикатор загрузки написанныый под VCL с использованием Direct2D.
      TD2DProgressBar = class(TCustomControl) FRenderTarget: ID2D1RenderTarget; FD2DFactory.CreateWicBitmapRenderTarget(FWicBitmap, RenderTargetProp, FRenderTarget); FInteropTarget := FRenderTarget as ID2D1GdiInteropRenderTarget; Вся отрисовка происходит на FRenderTarget.
      Затем беру
      FInteropTarget.GetDC(D2D1_DC_INITIALIZE_MODE_COPY, FRenderDC); и вывожу на поверхность функцией
       
      procedure TD2DProgressBar.UpdateWindow(sourceDC : HDC); var info : TUpdateLayeredWindowInfo; begin ZeroMemory(@info, sizeof(info)); with info do begin cbSize := sizeof(TUpdateLayeredWindowInfo); pptSrc := @FSourcePosition; pptDst := @FWindowPosition; psize := @FWndSize; pblend := @FBlend; dwFlags := ULW_ALPHA; end; info.hdcSrc := SourceDC; if not UpdateLayeredWindowIndirect(handle, @info) then begin RaiseLastOSError(); end end; Но это только под VCL.
      В Firemonkey не нашел способа комбинировать градиенты и/или нарисовать арку градиентом (саму линию арки а не залить сектор) или комбинацией градиентов.
       
      Как вывести этот FRenderTarget на канву Firemonkey-контрола?
      Самая большая проблема в том, что компонент полупрозрачный, и вариант с переливом через Vcl.Graphics.TBitmap и MemoryStream не дает нужного результата.
       
      MS:=TMemoryStream.Create; Blend.BlendOp := AC_SRC_OVER; Blend.BlendFlags := 0; Blend.AlphaFormat := AC_SRC_NO_PREMULT_ALPHA; Blend.SourceConstantAlpha:= 255; // // Уровень прозрачности Res:=Winapi.Windows.AlphaBlend(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, Blend); {или эта функция StretchBlt(bm.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, SRCCOPY); } VCLBitmap.SaveToStream(MS); FFMXBitmap.SetSize(TSize.Create(VCLBitmap.Width, VCLBitmap.Height)); FFMXBitmap.LoadFromStream(MS); FreeAndNil(MS);  
      В Blend пробовал разные комбинации BlendOp и AlphaFormat.
      Хелп плизз!
      Во вложении компонент под VCL. ( Может кому пригодится)) )
      D2DProgressbar.zip

    • От Ильдар
      Добрый день, идеология такая:
      - создать битмап, рисовать на нем, не делая его видимым.
      - нашлепать на канву панели подготовленный битмап.
       
      На деле не получается нарисовать линию на битмапе. Т.е после процедуры Draw2 прожимаю процедуру Draw - получаю на панели красный прямоугольник битмапа без нарисованной линии...
      Посоветуйте чего-нибуть, спасибо!
       
      //BITMAP Bm:= TBitmap.Create; bm.Width:= round (Panel.Width/2); bm.Height:= round (Panel.Height/2); bm.Canvas.BeginScene(); bm.Canvas.Clear(TAlphacolorrec.Red); //($FF484848); bm.Canvas.EndScene; procedure TChart.Draw2; var A,B:TPointF; begin A:=TPointF.Create(0,0); B:=TPointF.Create(200, 200); bm.Canvas.BeginScene(); bm.Canvas.DrawLine(A,B,1); bm.Canvas.EndScene; end; procedure TChart.Draw; var A: TPointF; R: TRectF; begin A.X:= Panel.Position.X+3; A.Y:= Panel.Position.Y+3; R:= TRectF.Create(A, bm.Width , bm.Height); panel.Canvas.BeginScene(); Panel.Canvas.DrawBitmap(bm,r,r, 20); panel.Canvas.EndScene; end;  
    • От Alisson R Oliveira
      привет всем
      У меня проблема в разработке алгоритма, который знает, что кто-то здесь может мне помочь. В сценарии и следующем, у меня есть изображение, которое отображает изображения, размещенные пользователями, так как фотографии могут быть нескольких разных размеров. Мне бы хотелось, чтобы высота проспекта (Image.Height) рассчитывалась в соответствии с размером экрана мобильного телефона (Android) или его ширина и изображение занимают высоту correda без размытия изображения, детали с использованием свойства Wrapmode: = fit; а не Wrapmode: = Растянуть
       
       
      благодарный
    • От S0lexV
      Доброго времени!
      Только начал знакомится с FMX, казалось бы от VCL отличий не так уж и много но все же....
      Пытаюсь загрузить картинку в ImageViewer (в Image тоже пробовал).
      ImageViewer1->Bitmap->LoadFromFile(System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "1.bmp")); Но получаю ошибку  (failed to loading bitmap "путь_к_папке_с_файлами_приложения"  )
      В deployment загружен файл "1.bmp", remote path прописан assets\internal
      Пробовал похожим способом загрузить с помощью deployment текстовый файл  в мемо все работает!
      Когда компилю под винду - картинка грузится, под андроид:  вылетает вышеуказанная ошибка
      PS Среда C++B10 Seattle
       
    • От Julia
      Загружаю через opendialog картинку  формата bmp в image
      Есть переменные с:TColor, c1:Tcolor
      Необходимо  вначале узнать цвет определенного пикселя на загруженной картинке и записать в  c1, а затем изменить цвет определенного пикселя на загруженной картинке на цвет, хранящийся в переменной c.
      Ищу очень давно, но внятного объяснения нигде не нашла(
       
       
    • От delphiec
      Беда, совсем беда .... Имеется на форме TListView (listviewEdit.jpg), в него динамически загружается список с картинками полученными через idhttp + TmemoryStream.
       
      ..... private nowDrawed:string; ... Item: TListViewItem; ImageObject: TListItemImage; TextObject: TListItemText; groups:array of Tgroups; ... ..... procedure Tmain.drawGroups(); var i:integer; begin try loader.Show; loader.ProgressBar.Max:=high(groups); loader.ProgressBar.Value:=0; Application.ProcessMessages; nowDrawed:='groups'; ListView.Items.Clear; ListView.BeginUpdate; for i := 0 to high(groups) do begin Item := ListView.Items.Add; TextObject:=Item.Objects.FindObjectT<TListitemtext>('Text'); TextObject.Text:=groups[i].caption; Item.Tag:=strtoint(groups[i].id); ImageObject:=Item.Objects.FindObjectT<TListItemImage>('Image'); if ImageObject.Bitmap=nil then ImageObject.bitmap:=TBitmap.Create; http.loadImage(url+groups[i].image,ImageObject.bitmap); loader.ProgressBar.Value:=i; Application.ProcessMessages; end; ListView.EndUpdate; loader.hide; except loader.hide; end; end; procedure Thttp.loadImage(link:string;bitmap:Tbitmap); var MS: TMemoryStream; begin try MS := TMemoryStream.Create; IdHTTP.Get(link,MS); MS.Position:=0; if not (bitmap=nil) then bitmap.LoadFromStream(MS); MS.Free; except end; end; Так вот, если собирать под Win64 (onWin.jpg), то всё отлично, но если под андроид (onAndr.jpg), то картинки отсутствуют. 
      При этом, если на форму бросить TImage и передавать в функцию loadImage bitmap этого Timage, то всё отображается корректно.
      P.S. Тестовое изображение в аттаче.




    • От Макс Войтенко
      Хотел сделать вот так (1 скриншот)

      Выбраная вкладка (аккаунты): иконка красная. А остальные вкладки чтобы иконка была серая. (как шрифт ниже).
      Подскажите как решить?
    • От MrSergei2017
      Я тут новичок, и не понимаю как использовать комманду CopyFromBitmap
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...