CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Mironas » wtorek, 7 sierpnia 2012, 18:52

Witam,
Czy ktoś ma pomysł jak wczytać GDI+ Bitmap do TAdvGlowButton.Picture ?
Wyjaśniam że jest to komponent z TMS Component Pack.
Jedyne co mi przychodzi do głowy to:
KOD cpp:     UKRYJ  
  BMP->Save(L"C:\\plik.png", &clsid);
  AdvGlowButton->Picture->LoadFromFile("C:\\plik.png");
 

.. ale to nie jest poważne.

Inne rozwiązanie to BMP zapisać do strumienia (IStream) zrobić konwersję do TStream i wczytać do AdvGlowButton->Picture. Ale konwersja
IStream >> TStream
też nie jest ciekawym rozwiązaniem. Mam funkcję która to robi ale wolałbym prostsze rozwiązanie.

Właściwość Picture jest klasy TGDIPPicture dziedziczącej po TGraphic.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » środa, 8 sierpnia 2012, 09:35

KOD cpp:     UKRYJ  
#include "memory"

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 String pathPNG = ExtractFilePath(ParamStr(0)) + "plik.png";
 imagePNG = new Gdiplus::Image(WideString(pathPNG).c_bstr());
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
 std::auto_ptr<Graphics::TBitmap> Bmp (new Graphics::TBitmap);

 Bmp->Width  = imagePNG->GetWidth();
 Bmp->Height = imagePNG->GetHeight();

 Gdiplus::Graphics grphxPNG(Bmp->Canvas->Handle);
 grphxPNG.DrawImage(imagePNG, 0, 0, imagePNG->GetWidth(), imagePNG->GetHeight());

 AdvGlowButton1->Picture->Assign( Bmp.get() );
}


Prostszej metody już nie znajdziesz.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Mironas » środa, 8 sierpnia 2012, 09:56

Tak, bitmapę Graphics::TBitmap można zassać do Picture (już to trenowałem) ale tu pojawia się następny problem. Lewy dolny piksel bitmapy traktowany jest jako kolor przeźroczystości. Wszystkie piksele na bitmapie o tym kolorze robią się przeźroczyste. Nie wiem jak to wyłączyć. Manipulowanie właściwością AdvGlowButton1->Picture->Transparent nic nie daje.

Problem przeźroczystości nie występuje jeśli obraz wczytam z pliku JPG/PNG/... np.:
KOD cpp:     UKRYJ  
AdvGlowButton1->Picture->LoadFromFile("C:\\plik.png");
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » środa, 8 sierpnia 2012, 11:00

KOD cpp:     UKRYJ  
#include "memory"
#include <jpeg.hpp>

void __fastcall TForm1::FormPaint(TObject *Sender)
{
 std::auto_ptr<Graphics::TBitmap> Bmp (new Graphics::TBitmap);

 Bmp->Width  = imagePNG->GetWidth();
 Bmp->Height = imagePNG->GetHeight();

 Gdiplus::Graphics grphxPNG(Bmp->Canvas->Handle);
 grphxPNG.DrawImage(imagePNG, 0, 0, imagePNG->GetWidth(), imagePNG->GetHeight());

 std::auto_ptr<TJPEGImage> Jpg (new TJPEGImage);

 Jpg->Assign( Bmp.get() );

 std::auto_ptr<TPicture> Pic (new TPicture);
 Pic->Assign( Jpg.get() );

 AdvGlowButton1->Picture->Assign( Pic.get() );
}


Tyle konwersji tylko po to, żeby umieść obraz z GDI+ na przycisku. Czy nie da się tego zrobić w inny sposób? Czy musi to być zawartość GDI+?

Mironas napisał(a):Lewy dolny piksel bitmapy traktowany jest jako kolor przeźroczystości.


Chyba prościej byłoby zmodyfikować kolor tego piksela by tylko ten jeden był przeźroczysty.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Mironas
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Mironas » środa, 8 sierpnia 2012, 11:37

Działa. Wielkie dzięki.
Faktycznie sporo tych konwersji ale to i tak lepsze niż przekazywanie przez plik na dysku lub za pomocą strumieni:
Gdiplus::Bitmap >> IStream >> bufor_uchar >> TStream >> AdvGlowButton1->Picture

Chociaż może powinienem sprawdzić na dużym obrazie który sposób jest szybszy.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez polymorphism » środa, 8 sierpnia 2012, 12:51

... >> IStream >> bufor_uchar >> TStream >> ...

Tak wystarczy: ... -> IStream -> TOLEStream -> ...
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Mironas
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Mironas » środa, 8 sierpnia 2012, 13:16

Tak wystarczy: ... --> IStream --> TOLEStream --> ...

Faktycznie dużo prościej. Dzięki.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » czwartek, 9 sierpnia 2012, 11:28

:? Wcześniej nie zwróciłem na to uwagi, ale istnieje bardzo prosty sposób rysowania na przycisku AdvGlowButton, trzeba tylko umieścić kod w jego zdarzeniu OnDrawButton:

KOD cpp:     UKRYJ  
void __fastcall TForm1::AdvGlowButton1DrawButton(TObject *Sender, TCanvas *Canvas,
          TRect &Rect, TGlowButtonState State)
{

 Gdiplus::Graphics grphxPNG(Canvas->Handle);
 grphxPNG. DrawImage(imagePNG, 0, 0, imagePNG->GetWidth(), imagePNG->GetHeight());

}
Zmiana zawartości imagePNG i grafiki, która będzie wyświetlana na przycisku jest proste, gdyż wystarczy zmienić tylko zawartość imagePNG, a obraz na przycisku zmieni się automatycznie. Przy takim rozwiązaniu imagePNG nie może być obiektem lokalnym, w moim przykładzie jest obiektem prywatnym.

Kompletny kod z przełączaniem grafiki.

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:        // User declarations
                Gdiplus::GdiplusStartupInput gdiplusStartupInput;
                ULONG_PTR gdiplusToken;

                 Gdiplus::Image *imagePNG;
Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
#define STRICT
//.............
#pragma link "gdiplus.lib"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
 String pathPNG = ExtractFilePath( ParamStr(0) ) + "plik.png";
 imagePNG = new Gdiplus::Image( pathPNG.c_str() );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AdvGlowButton1DrawButton(TObject *Sender, TCanvas *Canvas,
                  TRect &Rect, TGlowButtonState State)
{
 Gdiplus::Graphics grphxPNG( Canvas->Handle );
 grphxPNG. DrawImage( imagePNG, 0, 0, imagePNG->GetWidth(), imagePNG->GetHeight() );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AdvGlowButton1Click(TObject *Sender)
{
 /* Po naciśnieciu przycisku zmienia się grafika */
 if( imagePNG != NULL ) delete imagePNG;
 imagePNG = new Gdiplus::Image( L"c:\\image2.png" );
}


Ten sposób jednak różni się od wczytywania grafiki do właściwości Picture przycisku, gdyż zasłania cały przycisk wraz z tekstem na przycisku. To jest po prosty sposób na rysowanie na przycisku, a nie na wstawianie grafiki do przycisku.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Mironas
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Mironas » czwartek, 9 sierpnia 2012, 12:18

Dzięki za jeszcze jeden pomysł.
Dodałbym jeszcze delete imagePNG; na początku FormDestroy:
KOD cpp:     UKRYJ  
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 delete imagePNG;
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
 
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » czwartek, 9 sierpnia 2012, 12:32

Tak, tego zabrakło, chociaż Windows i tak by to chyba posprzątał.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez polymorphism » czwartek, 9 sierpnia 2012, 12:56

Panowie, auto_ptr używać gdzie się tylko da!
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » czwartek, 9 sierpnia 2012, 13:21

W podanym przeze mnie przypadku chyba się nie da, gdyż mamy do czynienia z obiektem prywatnym nie lokalnym. Chociaż będę musiał to sprawdzić, przy czym należy pamiętać, że imagePNG musi istnieć przez cały czas działania programu, gdyż grafika jest pobierana przez zdarzenie OnDrawButton zawsze gdy zachodzi konieczność odświeżenia grafiki tego przycisku.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez polymorphism » czwartek, 9 sierpnia 2012, 13:27

W podanym przeze mnie przypadku chyba się nie da, gdyż mamy do czynienia z obiektem prywatnym nie lokalnym.

To nie ma znaczenia:
KOD cpp:     UKRYJ  
private:
        std::auto_ptr<Gdiplus::Image> imagePNG;
        ...

imagePNG.reset( new Gdiplus::Image( pathPNG.c_str() ) );
...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez Cyfrowy Baron » piątek, 10 sierpnia 2012, 09:36

Podany przeze mnie sposób ze zdarzeniem OnDrawButton można jeszcze udoskonalić:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:
                Gdiplus::GdiplusStartupInput gdiplusStartupInput;
                ULONG_PTR gdiplusToken;

                Gdiplus::Image *imagePNG;
Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
#pragma link "gdiplus.lib"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 String pathPNG = ExtractFilePath(ParamStr(0)) + "plik.png";
 imagePNG = imagePNG->FromFile(pathPNG.c_str(), false);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AdvGlowButton1DrawButton(TObject *Sender, TCanvas *Canvas,
                  TRect &Rect, TGlowButtonState State)
{
 Gdiplus::Graphics grphxPNG(Canvas->Handle);
 grphxPNG.DrawImage(imagePNG, 0, 0, imagePNG->GetWidth(), imagePNG->GetHeight());
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AdvGlowButton1Click(TObject *Sender)
{
 imagePNG = imagePNG->FromFile( L"c:\\image2.png", false );
}


Ponieważ nie użyłem operatora new to wydaje mi się, że nie ma potrzeby niszczyć obiektu przy zamknięciu programu. Podany sposób ma nad poprzednim tą przewagę, że bez niszczenia obiektu można wczytywać kolejno pliki. Niestety z funkcją auto_ptr nic mi nie wyszło.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: GDI+ Bitmap do TAdvGlowButton.Picture [komponent TMS]

Nowy postprzez polymorphism » piątek, 10 sierpnia 2012, 10:12

Ponieważ nie użyłem operatora new to wydaje mi się, że nie ma potrzeby niszczyć obiektu przy zamknięciu programu.

Image::FromFile tworzy instancję operatorem new, więc dobrze by było ją zwolnić. Zresztą Twój kod dopuszcza możliwość wielokrotnego tworzenia obiektów (vide AdvGlowButton1Click), zatem niezwalnianie obiektów imagePNG jest błędem, który powoduje wycieki pamięci/zasobów.

Niestety z funkcją auto_ptr nic mi nie wyszło.

A co tam mogło nie wyjść?



Mała uwaga. Metody statyczne wywołuj w ten sposób:
KOD cpp:     UKRYJ  
imagePNG = Image::FromFile( L"c:\\image2.png", false );

ponieważ wtedy wiadomo, bez analizy dokumentacji, co robisz.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 8 gości

cron