Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: marrosso - Marzo 22, 2025, 03:47:59 pm

Titolo: Problema con BitMap
Inserito da: marrosso - Marzo 22, 2025, 03:47:59 pm
Se faccio degli errori riprendetemi pure perché sono inesperto, vorrei sottoporvi un problema, ho disegnato sul form dei cerchi con le canvas del form ma siccome non ero soddisfatto della qualità li ho disegnati pixel-pixel e poi ho applicato l'algoritmo di Bresenham per ottimizzare le transizioni affette da aliasing con buon successo, ma il problema è che il form non presenta la proprità Autoredraw e i cerchi si cancellano al resize e in altri momenti, quindi ho pensato di utilizare BitMap per renderlo stabile ma quando cerco di acccedere alla calvas di BitMap il programma si blocca e x uscire devo usare Esc. potete suggerirmi come risolvere? vorrei che il disegno dei cerchi fatto col metodo pixels fosse permanente sul form, grazie della comprensione
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 22, 2025, 04:39:38 pm
Ciao, non posso aiutarti specificatamente perchè non ho Lazarus in questo momento però ti accenno due indicazioni presupponendo che tu stia lavorando in Windows.

In generale tutto cio che è un componente grafico derivato dai controlli di Windows per essere "sovrascritto" rispetto al design time deve essere continuamente "rinfrescato" ossia ridisegnato (e non sempre ciò funziona, vedi i controlli TCheckBox e simili o il TButton). Si usa l'evento OnPaint per disegnare o scrivere nel controllo qualsiasi cosa tu voglia disegnare a runtime (compreso il testo per alcune tipologie di controlli quali le griglie).

Per ovviare a ciò ci sono dei specifici componenti che possono essere usati a runtime per consentire di disegnare forme basi come cerchi rettangoli stondati o no, lo TShape è uno di questi che può essere usato sia a design time che a runtime.

Se vuoi disegnare sulla form, usa il metodo OnPaint e dentro li ci scrivi la tua routine.

Nell'esempio che ti propongo vedrai che scrivendo una sola volta appare il quadrato permanente, ma per alcuni controlli ciò và fatto in continuo quindi togliendo l"IF"

La FORM DEVE ESSERE ALMENO DI 301 x 301 PIXEL affinchè il codice sotto riportato funzioni.

Codice: [Seleziona]
var tip: integer = 0; //và dichiarata nella sezione "interface"

procedure TForm1.FormPaint(Sender: TObject);
begin
  if tip = 0 then  //con questo scrive solo una volta
    begin
      self.Canvas.Rectangle(100, 100, 300, 300);
      inc(tip);
    end;
end;

P.S.: fai attenzione al codice che inserisci nell'evento, stai occupando il thread principale e quindi "la pompa" dei messaggi di Windows. Se la tua routine impiega molto tempo l'applicazione diventerà instabile (diciamo "not responsive") fino al limite estremo del crash.
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 22, 2025, 04:46:06 pm
A proposito, me ne ero dimenticato, ci dovrebbe essere un componente TPaintBox che viene usato come superficie grafica proprio per questi scopi (anche ad uso diretto dell'utente).
Titolo: Re:Problema con BitMap
Inserito da: nomorelogic - Marzo 22, 2025, 04:49:28 pm
Non so a che livello di qualità vuoi arrivare.
Vedo però che cerchi di perfezionare il risultato.

Ti vorrei segnalare questa Liberia
https://wiki.freepascal.org/BGRABitmap_tutorial (https://wiki.freepascal.org/BGRABitmap_tutorial)

Visto che sei all' inizio vedere le varie opzioni non fa mai male 😉
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 22, 2025, 05:17:50 pm
Già che ci siamo allora dai una letta anche a Skia:

https://wiki.freepascal.org/Skia (https://wiki.freepascal.org/Skia)

P.S.: in Delphi Skia è (dovrebbe con l'ultima release) integrata e non c'è necessità di DLL, in Lazarus se non sbaglio c'è necessità della DLL apposita a runtime. Potrei sbagliare in quanto stanno sviluppando novità su Skia praticamente ogni settimana.
Titolo: Re:Problema con BitMap
Inserito da: marrosso - Marzo 23, 2025, 12:57:00 pm
Grazie per le risposte, bgrabitmap non riconosce le TImage, probabilmente c'è qualche problema di compatibilità, mentre Skia non sono riuscito ad installarla, forse non esite per Lazarus?
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 23, 2025, 01:53:32 pm
... mentre Skia non sono riuscito ad installarla, forse non esite per Lazarus?

Sei andato al link che ti ho indicato ?

Già che ci siamo allora dai una letta anche a Skia:
https://wiki.freepascal.org/Skia (https://wiki.freepascal.org/Skia)

Li trovi le istruzioni per installare Skia. I primi link di skia4delphi sono indicati solo per installare la dll / so (che trovi comodamente qua: https://github.com/skia4delphi/skia4delphi/tree/main/Binary/Shared (https://github.com/skia4delphi/skia4delphi/tree/main/Binary/Shared) )

Poi segui gli altri link per scaricare il pacchetto per Lazarus / FPC
Titolo: Re:Problema con BitMap
Inserito da: Mimmo - Marzo 24, 2025, 08:35:52 am
Ciao!
Io utilizzo BGRABitmap (che ti ha segnalato nomorelogic) per un po' di cose e, a parte l'iniziale difficoltà a capirne un po' la logica, non posso che parlarne bene. Se ti interessi di grafica, potrebbe essere interessante. E' tutto codice pascal per cui viene tutto compilato dentro il tuo programma. E' un'ottima soluzione ad esempio se hai bisogno di creare un programma privo delle lcl (quindi niente GUI) che deve però effettuare operazioni di grafica tipo generare immagini.
Skia non l'ho mai usato anche se ne ho letto bene perchè è potente e cross-platform, l'unica cosa però è che sul wiki dice che è compatibile con fpc 3.3.1 mentre il compilatore distribuito con l'ultima release ufficiale di Lazarus è ancora il 3.2.2. Magari funziona anche con quello però devi verificare.
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 24, 2025, 09:13:32 am
....
Skia non l'ho mai usato anche se ne ho letto bene perchè è potente e cross-platform, l'unica cosa però è che sul wiki dice che è compatibile con fpc 3.3.1 mentre il compilatore distribuito con l'ultima release ufficiale di Lazarus è ancora il 3.2.2. Magari funziona anche con quello però devi verificare.
....

OOPS  :o :o :o non avevo notato quel prerequisito ..... chiedo venia.

@marrosso

Allora prosegui con le BGRABitmap.

Ciao e scusate ancora la imprecisione.

Titolo: Re:Problema con BitMap
Inserito da: nomorelogic - Marzo 24, 2025, 10:07:26 am
Grazie per le risposte, bgrabitmap non riconosce le TImage, probabilmente c'è qualche problema di compatibilità[...]

non vorrei ci fosse un malinteso:
la classe TBGRABitmap la devi usare al posto di TImage


https://wiki.freepascal.org/BGRABitmap_tutorial_2 (https://wiki.freepascal.org/BGRABitmap_tutorial_2)
Titolo: Re:Problema con BitMap
Inserito da: marrosso - Marzo 25, 2025, 03:26:11 pm
Buon giorno, ho risolto il problema dell'autoredraw del form, facendo cosi, per prima cosa ho creato un variabile Bitmap a livello di classe del form, poi l'ho inizializzata su OnCreate del Form e quando ha finito di caricare immagini, shape e disegni fatti col metodo Pixel ho salvato l'immagine sulla Bitmap cosi:     <Form1.Bitmap.SetSize(Form1.ClientWidth, Form1.ClientHeight);
Form1.Bitmap.Canvas.CopyRect(Rect(0, 0, Form1.ClientWidth, Form1.ClientHeight),
                             Form1.Canvas,
                             Rect(0, 0, Form1.ClientWidth, Form1.ClientHeight));>
        cosi carico limmagine sulla BitMap e poi col metodo Paint la scarico sul Form cosi:
<procedure TForm1.FormPaint(Sender: TObject);
begin
  // Disegna la bitmap colorata sul form
  Form1.Canvas.Draw(0, 0, Form1.Bitmap);
end; >
con questo semplice accorgimento posso disegnare e caricare sul form qualunque cosa che rimane in memoria sullo schermo, con un unico accorgimento di non avere il form fuori dallo schermo, quindi col metodo resize lo faccio rientrare nella finestra, altrimenti la Bitmap non carica l'immagine fuori schermo:
<procedure TForm1.FormResize(Sender: TObject);
begin
  // Controllo limiti orizzontali
  if Left + Width > Screen.Width then
    Left := Screen.Width - Width - 100;
  if Left < 0 then
    Left := 0;

  // Controllo limiti verticali
  if Top + Height > Screen.Height then
    Top := Screen.Height - Height - 100;
  if Top < 0 then
    Top := 0;
end;>


           Grazie a tutti e spero che la mia idea possa servire a qualcuno.
Titolo: Re:Problema con BitMap
Inserito da: DragoRosso - Marzo 25, 2025, 06:42:02 pm
C'è una soluzione molto più semplice:

a design time ci piazzi una TImage sulla Form, poi se vuoi o sempre a design time o a runtime setti la proprietà "Align" della TImage a "alClient".
Setta poi le proprietà della TImage (come "proportional", "stretch", etc ..).

Ora caricati una qualsiasi immagine nella TImage di base oppure anche a runtime, oopure crei una bitmap nella TImage direttamente a runtime.

Ora nella Canvas della TImage puoi farci quello che vuoi, disegnarci, copiarci, etc ... e vedrai che spostando la form, rimpicciolendola, posizionandola tra due schermi la tua TImage verrà sempre rinfrescata e mantenuta.

Codice: [Seleziona]
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Canvas.Brush.Color := clGreen;
  Image1.Canvas.Pen.Color := clRed;
  Image1.Canvas.Pen.Width := 5;
  Image1.Canvas.Pen.Style := psSolid;
  Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Picture.Bitmap.Create(Image1.Width, Image1.Height);
end;