JPEGImage + ProgressBar

Dyskusje na dowolny temat.

JPEGImage + ProgressBar

Nowy postprzez Witold » czwartek, 28 stycznia 2010, 13:22

Cyfrowy Baron napisał(a):
Tu nie chodzi o kompresje czy dekompresje, lecz o wczytywanie i zapisywanie. O ile zdarzenie OnProgress dla TImage i plików w formacie JPEG działa bez zarzutu, o tyle w przypadku samej tylko klasy TJPEGImage już wogóle nie działa.


tyle że wczytywanie twa 8mb trwa ułamek sekundy, kompresja / dekompresja raczej dłużej. TImage zapewne musi przeprowadzić dekompresje przed wyświetleniem obrazka, dlatego generuje pośrednio OnProgress:
Kod: Zaznacz cały
__property Graphics::TPicture* Picture = {read=FPicture, write=SetPicture};


Kod: Zaznacz cały
constructor TImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  FPicture := TPicture.Create;
  FPicture.OnChange := PictureChanged;
  FPicture.OnProgress := Progress; <-------------------------------------------------------------------------------------
  Height := 105;
  Width := 105;
end;


Te fragment pomocy o TPicture::OnProgress jednak raczej zacytowałem dobrze, polecam przeczytać.

przeczytałem, jest ogólny nie o TJPEGImage.


Cyfrowy Baron napisał(a):Nie jest ogólny, gdyż został umieszczony pod tym cytatem:
after I replaced TImage with TBitmap and some other minor
changes to make it comile, the OnProgress event is not invoked.



Tyczy się TBitmap nie TJPEGImage?

Cyfrowy Baron napisał(a):Skoro twierdzisz, że jest inaczej, to podaj działający kod.


Lepiej sam sobie napisz, wczytaj JPG do TJPEGImage i przepisz go do TBitmap’y (dekompresja), wtedy u mnie obsługa OnProgress jest wywoływana.

Cyfrowy Baron napisał(a):Konwersji nie możną dokonać poprzez Assign, jak wspomniałem wcześniej ta funkcja służy tylko do kopiowania jednego obiektu na drugi, ale obiekt A do którego się kopiuje obiekt B, musi obsługiwać klasę obiektu A. Klasa TPicture obługuje zarówno klasę TJPEGImage jak i TBitmap, ale TJPEGImage nie obsługuje TBitmap, więc samo kopiowanie nic nie da trzeba przerysować obiekt typu TJPEGImage do obiektu typu TBitmap.


Ty sobie to wymyślasz czy jak ?
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: JPEGImage + ProgressBar

Nowy postprzez Cyfrowy Baron » czwartek, 28 stycznia 2010, 14:04

Lepiej sam sobie napisz, wczytaj JPG do TJPEGImage i przepisz go do TBitmap’y (dekompresja), wtedy u mnie obsługa OnProgress jest wywoływana.


Co mi po dekompresji czy kompresji.

Czytaj uważnie. Gdy wczytuję do TImage plik w formacie JPEG to zdarzenie OnProgress jest wywoływane i wyświetlany jest pasek postępu. Gdy ten sam plik wczytuję do TJPEGImage to zdarzenie OnProgress nie jest wywoływane i pasek postępu nie jest wyświetlany.

Gdy kopiujesz plik z TJPEGImage do TImage a zdarzenie OnProgress masz podłączone pod TImage to zdarzenie OnProgress obiektu TImage jest wywoływane pośrednio ze względu na kompresję, ale bezpośrednio ze względu na proces kopiowania, co oczywiście wiąże się bezpośrednio z dekompresją.

Jednak od samego początku nie o to chodzi, lecz o to, żeby podłączyć zdarzenie OnProgress i wizualizować w ProgressBar proces wczytywania pliku do TJPEGImage bez konieczności używania TImage, ale jeżeli zdarzenie OnProgress jest podłączone pod TJPEGImage to tej wizualizacji nie ma, gdyż TJPEGImage nie wywołuje tego zdarzenia.

Podsumowując. Jeżeli pod TImage podłącze zdarzenie OnProgress i przekopiuję do TImage obiekt typu TJPEGImage to proces kopiowania, nie wczytywania pliku jest wizualizowany, tak więc zdarzenie OnProgress tyczy się tylko kompresji i dekompresji grafiki przed wyświetleniem w TImage, a nie wczytywania i zapisywania, na co najlepszym dowodem jest to, że obiekt klasy TJPEGImage nie dekompresuje grafiki podczas wczytywania, lecz wczytuje ją taka jaka jest i dlatego zdarzenie OnProgress nie jest wywoływane.

Tak jak ty piszesz, to ja już za pierwszym razem zrobiłem przez pomyłkę podłączając zdarzenie OnProgress nie pod TJPEGImage lecz pod TImage, a pomyliłem się dlatego, że obydwa obiekty nazwałem podobnie, czyli TJPEGImage *Image i TImage *Image1. Zanim się zorientowałem, uznałem, że to TJPEGImage steruje ProgressBar, ale po poprawce i podpięciu zdarzenie pod TJPEGImage niestety przestało działać.

Jeżeli zrobię to tak:

Kod: Zaznacz cały
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
Image = new TJPEGImage();

Image->ProgressiveDisplay = true;
Image1->OnProgress = ImageProgress;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ImageProgress(TObject *Sender, TProgressStage Stage,
     BYTE PercentDone, bool RedrawNow, const TRect &R, const AnsiString Msg)
{
switch(Stage)
{
  case psStarting: ProgressBar1->Position = 0; break;
  case psRunning:  ProgressBar1->Position = PercentDone; break;
  case psEnding:   ProgressBar1->Position = 100; break;
}

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(OpenPictureDialog1->Execute())
{
  Image->LoadFromFile(OpenPictureDialog1->FileName);
  Image1->Picture->Assign(Image);
}   
}
//---------------------------------------------------------------------------


Zauważ jednak, że zdarzenie OnProgress zostało podłączone pod Image1 (TImage), a proces wizualizacji jest realizowany nie tutaj:

Kod: Zaznacz cały
  Image->LoadFromFile(OpenPictureDialog1->FileName);


lecz tutaj:

Kod: Zaznacz cały
  Image1->Picture->Assign(Image);


więc nie podczas wczytywania, lecz podczas kopiowania obiektu.



Jeżeli dokonam drobnej modyfikacji i podłącze zdarzenie OnProgress pod Image (TJPEGImage):

Kod: Zaznacz cały
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
Image = new TJPEGImage();

Image->ProgressiveDisplay = true;
Image->OnProgress = ImageProgress;
}
//---------------------------------------------------------------------------


To teraz zdarzenie OnProgress dla TJPEGImage nie zostanie wywołane, gdyż w Image (TJPEGImage) nie zachodzi proces dekompresji, zachodzi jednak w Image1 (TImage) podczas kopiowania.

A przecież pytanie mervinjmicky brzmiało:

Chciałbym do mojej funkcji dodać postęp wczytywania pliku JPG. Nie używam TImage tylko


Zwracam uwagę na fragment: Nie używam TImage, a skoro nie używa TImage, a jedynie TJPEGImage to nie ma dekompresji, gdyż TJPEGImage może przechowywać pliki JPEG skompresowane.



Tutaj przyznaję, że nie od razu zrozumiałem przyczynę tego, że TImage obsługuje OnProgress a TJPEGImage już nie mimo iż wczytywane są do obydwu pliki JPEG. Początkowo sądziłem, że OnProgress odnosi się do wczytywania plików a nie do dekompresji, ale to Ty zasugerowałeś to swoją pierwszą odpowiedzią w tym wątku, więc nie wiem, czy też zdawałeś sobie sprawę, że tyczy się to kompresji, a nie wczytywania.



Nie do końca wiem jak to jest z tą kompresją, gdyż przy próbie poddanie pliku JPEG kompresji i przepisania go do Image wyskakuje błąd:

JPEG error #42



Podejrzewam, że jest to spowodowane tym, że próbuje poddać kompresji plik już skompresowany, a przed kompresją należałoby go najpierw zdekompresować, ale już mi się nie chce dzisiaj tego testować.
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: JPEGImage + ProgressBar

Nowy postprzez Witold » czwartek, 28 stycznia 2010, 20:27

Ani przez chwilę nie twierdziłem że OnProgress zostanie przez TJPEGImage obsłużone przy wczytywaniu (LoadFromFile). Założyłem jedynie że „Obsługa zdarzenia TJPEGImage::OnProgress może okazać się pomocna” , posiłkując się wiedzą ile zajmuje (u mnie) wczytanie/zapisanie pliku (z/na HDD) a ile jego kompresja/dekompresja przy JPG wielkości 8mb, i tym że nie miałem pewności jak przebiega zapis/odczyt u mervinjmicky’a. Podstawy nie za mocne, trochę domysłów, ale chyba założyłem słusznie:

mervinjmicky napisał(a):Do tej pory robiłem to tak:
Kod: Zaznacz cały
  TJPEGImage *jpg = new TJPEGImage();
   Graphics::TBitmap *bmp = new Graphics::TBitmap();
   jpg->LoadFromFile(File);
   bmp->Assign(jpg);
   int height=0;
   int procent = (width*100)/bmp->Width;
   height = (bmp->Height*procent)/100;
   bmp->Canvas->StretchDraw(Rect(0, 0, width, height), bmp);
   bmp->Height = height;
   bmp->Width = width;
   jpg->Assign(bmp);
   jpg->CompressionQuality = quality;
   jpg->SaveToFile(temp+"\\\\miniatura1.jpg");
   jpg->Free();
   bmp->Free();


Kolega wczytuje/dekompresuje/zmienia height’a/kompresuje/zapisuje. Obsłużenie TJPEGImage::OnProgress w tym wypadku byłoby sensowne.


Ty napisałeś „Ale klasa TJPEGImage jak i TBitmap nie maja wsparcia dla tego zdarzenie..” (OnProgress) co jest nieprawdą, ma wsparcie przy kompresji/dekompresji. Gdybyś napisał „Ale klasa TJPEGImage jak i TBitmap nie maja wsparcia dla tego zdarzenie przy wczytywaniu
LoadFromFile”, nie byłoby dalej o czym pisać. Sam wmieszałeś w wątek TImage nie wiem po co? A potem cytujesz „Nie używam TImage”.

Przyznaje źle zrozumiałem o co Ci kilka razy chodzi, wobec tego kilka moich odpowiedzi jest nie trafionych.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera

Re: JPEGImage + ProgressBar

Nowy postprzez Cyfrowy Baron » czwartek, 28 stycznia 2010, 20:48

Przyznaje źle zrozumiałem o co Ci kilka razy chodzi, wobec tego kilka moich odpowiedzi jest nie trafionych.


Najwyraźniej wogóle nie zrozumiałeś pytania, gdyż na pytanie:

Chciałbym do mojej funkcji dodać postęp wczytywania pliku JPG. Nie używam TImage tylko


udzieliłeś odpowiedzi:

Obsługa zdarzenia TJPEGImage::OnProgress może okazać się pomocna, szczegóły w helpie.


Idąc tym tropem, próbowałem bezskutecznie podłączyć wczytywanie pliku pod zdarzenie OnProgress, co okazało się niemożliwe. Sam namieszałeś, a teraz się wypierasz.
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: JPEGImage + ProgressBar

Nowy postprzez Witold » czwartek, 28 stycznia 2010, 21:19

Cyfrowy Baron napisał(a):
Przyznaje źle zrozumiałem o co Ci kilka razy chodzi, wobec tego kilka moich odpowiedzi jest nie trafionych.


Najwyraźniej wogóle nie zrozumiałeś pytania, gdyż na pytanie:


Zobacz co zacytowałem przy tej odpowiedzi -> "Gdy są to pliki 8mb i większe to chwile to trwa dlatego chciałbym umieścić ProgressBar'a na formatce i tam pokazywać status. Czy jest coś takiego możliwe?" po tym była odpowiedz! Ustosunkowałem się do części. Zapisywanie 8 MB zajmuje mało czasu, kompresja więcej (u mnie).

Cyfrowy Baron napisał(a):Idąc tym tropem, próbowałem bezskutecznie podłączyć wczytywanie pliku pod zdarzenie OnProgress, co okazało się niemożliwe.


Nie napisałem że to będzie działać przy wczytywania, więc nie musiałeś tego robić. Gdyby pytający wyraził zainteresowanie OnProgress, wyjaśniłbym wszystko.

Cyfrowy Baron napisał(a):Sam namieszałeś, a teraz się wypierasz.

Nie wypieram się, napisałem jak było. Zresztą, mervinjmicky jeżeli wprowadziłem Cię w błąd/namieszałem to przepraszam.

Co może dla tego kodu mervinjmicky’a który zacytowałem obsłużenie TJPEGImage::OnProgress nie ma sensu?
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    Windows XPOpera


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Dyskusje

Kto przegląda forum

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

cron