Ĺadny brzuch
Chym... w Win jest taka opcja jak " pokazuj miniatury " - Jezeli w katalogu sa same obrazki - zaluzmy *.jpg - to windows robi miniaturki tych obrazkow potem zapisuje je w pliku Tumb... , gdy user otworzy ten katalog innym razem to win juz nie robi miniatur tylko czyta je z tego pliku Tumb - co powoduje ze miniatury otwieraja sie " prawie " natychmiastowo . Chcialbym zrobic cos takiego . Napisalem juz otwieranie obrazkow i robienie miniatur . Powiedzmy katalog ktory zawiera 500 jpgów ( 1024 x 768) to miniatury ( 100 x 100 px) wszystkich 500 obrazkow zajmuja jakies 1MB .
Napisalem program ktory wyszukuje pliki *.jpg w katalogu i wyswietla je w postaci miniatur - jest szybko ale chcialbym przy kolejnym otwarciu katalogu by juz nie musial robic miniatur tylko by dzialalo to tak jak w Win .
Ale utknołem na tym ze
1. Trzeba chyba zapisywac miniatury do jakies "bazy" (narazie zapisuje do katalogu Temp)
2. Przy ponownym otwieraniu katalogu - zeby moj program korzystal z tej " bazy "
3. Oczywiscie jak rozwiazac problem by odpowiednia miniatura odpowiadala jej orginalowi
4. Jezeli do katalogu dorzuce 1 obraz to nie chce by program zmuszony byl robic wszystkie miniatury na nowo .
No i jeszcze wiele wiele utkniec ale jezeli ktos wie jak rozwiazac tan problem to cala reszta bedzie latwa :)
prawdziwych programistow juz nie ma :-(
Wiec w kazdym katalogu po zindkesowaniu zapisuj miniatury do pliku thumbs.mydb ;) albo innego. Zrob se rekord i zadeklaruj
TMyFileInfo= record FName:array[0..255] of char; FThumb:pointer; end; PMyFileInfo=^TMyFileInfo; TMyFilesList : array of PMyFileInfo; var f: file of TMyFilesList;
Fthumb zawiera miniature a FName - nazwe danej miniatury
Mozna by jeszcze dodac sume crc ale by wiecej trwalo (za to pewnosc ze jak podmienisz plik na inny to nie wywali "starej" miniatury)
//Pisane z glowy nie wiem czy zadziala
Użytkownik migajek edytował ten post 01 kwiecień 2005, 16:26
THX - migajek - sprawdze to ale z tym crc to nie taki zly pomysl by jednak jakos musze sie zabezpieczyc przed podmienianiem plikow , zmiana nazw itp ..
A gdybys mogl mi jeszcze podpowiedziec - zeby dodawac rekordy (miniatury ) tylko te np: gdy do juz utworzonego katalogu ( tumba) powiedzmy dorzuce pare tapet - to zeby nie tracic czasu i energi program musial by do juz utworzonego tumba dopisywac tylko te tapety kturych jeszcze nie ma w nim .
No ale najwazniejsze to jak te wszystkie miniatury zapisywac do jednego pliku ?
a tak na marginesie to jak sprawdzac CRC
Witam. No właśnie ja też się spotkałem niedawno z problemem jak zapisać do pliku kilka obrazów i oprócz tego jak nimi w miarę sprawnie zarządzać :). Wtedy to zrodził się mały pomysł aby wykorzystać do tego pliki... INI. No i wszystko było by nawet ok gdyby nie to że, zapisać obraz do takiego pliku można z całkowitą łatwością ale już z odczytem pojawił się straszny problem gdyż standartowo maksymalna długość odczytanego tekstu nie przekracza 2048 znaków co przy nawet sporej kompresji pliku jest długością całkowicie niewystarczającą :). Drugi problem jest taki że jeśli plik ma np. 1MB to po zapisaniu do pliku INI ma już ich 2. Ale wykorzystując kompresje i wielkość 100x100 można przy odczycie ok pięćsetnej pozycji uzyskać czas ok 0.8 do 0.9 sek. gorzej z zapisem na to potrzebowałem do zapisania 500 pozycji (bmp 800x600 kompresja 70%) min 14 sek uzyskując plik 2,3 MB. Dopisywanie kolejnych pozycji przegiegało już dość sprawnie. No a teraz konkrety he he. Oczywiście koło profesjonalizmu to nigdy nie leżało ale może się przyda :).
Zapis do pliku to funkcja:
Index: Pod jaką nazwą zostanie zapisana pozycja Image: nie trzeba tłumaczyć ImageWidth: max szerokość obrazka ImageHeight: max wysokość obrazka CompressQuality: stopień kompresji Stretch: czy obraz ma być dopasowany do zadanej wielkości czy przeskalowany w proporcji function WritePictureJpeg(Index: String; Image: TGraphic; ImageWidth, ImageHeight, CompressQuality: Integer; Stretch: Boolean): Boolean; var TMS: TMemoryStream; Text: String; Ini: TIniFile; Bmp: TBitmap; Jpg: TJpegImage; begin Result:= False; try // Utworzenie obrazów Bmp:= TBitmap.Create; Jpg:= TJpegImage.Create; // Ustalenie rozmiarów obrazka // Jeżeli Stretch jest True if Stretch then begin // Zmiana roziaru obrazka Bmp.Width:= ImageWidth; Bmp.Height:= ImageHeight; end else begin // Jeśli obraz ma być proporcjonalny wtedy przeskaluj if Image.Width >= Image.Height then begin Bmp.Width:= ImageWidth; Bmp.Height:= Ceil((ImageWidth / Image.Width) * Image.Height) end else begin Bmp.Width:= Ceil((ImageHeight / Image.Height) * Image.Width); Bmp.Height:= ImageHeight; end; end; // Pobranie obrazka Bmp.Canvas.StretchDraw(Rect(0, 0, Bmp.Width, Bmp.Height), Image); Jpg.Assign(Bmp); // Kompresja pliku jpg.CompressionQuality:= CompressQuality; Jpg.DibNeeded; Jpg.Compress; // Utworzenie strumienia TMS:= TMemoryStream.Create; // Załadowanie strumienia Jpg.SaveToStream(TMS); // Procedura zamaiany strumienia w tekst TMS.Position:= 0; SetLength(Text, (TMS.Size - TMS.Position) * 2); BinToHex(PChar(Integer(TMS.Memory) + TMS.Position), PChar(Text), TMS.Size - TMS.Position); // Zpisanie do pliku Ini:= TIniFile.Create('C:\Ala\eee.ini'); Ini.WriteString(Index, 'Value', Text); Ini.Free; Result:= True; finally TMS.Free; Bmp.Free; Jpg.Free; end; end; A teraz odczyt: function ReadPictureJpeg(Index: String; Image: TJpegImage): Boolean; var Stream: TMemoryStream; Text: String; ListString: TStringList; Position: Integer; begin Result:= False; { if not (Image is TJpegImage) then Exit; } try Stream:= TMemoryStream.Create; Text:= ''; ListString:= TStringList.Create; // Załadowanie listy ListString.LoadFromFile('C:\Ala\eee.Ini'); // Pobranie tekstu Text:= ListString.Strings[ListString.IndexOf('[' + Index + ']') + 1]; // Usunięcie identyfikatora Delete(Text, 1, 6); // Otrzymany tekst przerabiamy na wartość binarną if Text <> '' then begin Position:= Stream.Position; Stream.SetSize(Stream.Size + Length(Text) div 2); HexToBin(PChar(Text), PChar(Integer(Stream.Memory) + Stream.Position), Length(Text) div 2); Stream.Position := Position; // if Stream <> nil then begin Image.LoadFromStream(Stream); Result:= True; end; end; finally // Zwolnienie zmiennych ListString.Free; Stream.Free; end; end;
Może się nada. Pozdrawiam.
// dodanie codebox
Użytkownik _Herkules_ edytował ten post 02 kwiecień 2005, 11:44
BumaDruma: E... sorry... ale to chyba nie jest najlepszy pomysl.
Helios: o crc masz na 4p,
co do dopisywania : otwierasz plik z miniaturami, po kolei je wyswietlasz (jesli suma crc zapisana w rekordzie jest rowna wyliczonej z konkretnego pliku) jesli nie to nadpisujesz dana miniature, czyli np. przy ladowaniu wszystkie miniatury zapisujesz do tablicy, zmieniasz element o niepasujacym crc i zpisujesz spowrotem - jesli zas pojawily sie nowe pliki to dopisujesz je na koncu.
Użytkownik migajek edytował ten post 02 kwiecień 2005, 09:56
ok THX - BumaDruma -
wszystko fajnie ale chyba jednak sprobuje w inny sposob.
Chcialbym raczej zapisywac do bazy a nie do ini . Ale i tak wiekie THX :)
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
Napisalem program ktory wyszukuje pliki *.jpg w katalogu i wyswietla je w postaci miniatur - jest szybko ale chcialbym przy kolejnym otwarciu katalogu by juz nie musial robic miniatur tylko by dzialalo to tak jak w Win .
Ale utknołem na tym ze
1. Trzeba chyba zapisywac miniatury do jakies "bazy" (narazie zapisuje do katalogu Temp)
2. Przy ponownym otwieraniu katalogu - zeby moj program korzystal z tej " bazy "
3. Oczywiscie jak rozwiazac problem by odpowiednia miniatura odpowiadala jej orginalowi
4. Jezeli do katalogu dorzuce 1 obraz to nie chce by program zmuszony byl robic wszystkie miniatury na nowo .
No i jeszcze wiele wiele utkniec ale jezeli ktos wie jak rozwiazac tan problem to cala reszta bedzie latwa :)
prawdziwych programistow juz nie ma :-(
Wiec w kazdym katalogu po zindkesowaniu zapisuj miniatury do pliku thumbs.mydb ;) albo innego. Zrob se rekord i zadeklaruj
TMyFileInfo= record FName:array[0..255] of char; FThumb:pointer; end; PMyFileInfo=^TMyFileInfo; TMyFilesList : array of PMyFileInfo; var f: file of TMyFilesList;
Fthumb zawiera miniature a FName - nazwe danej miniatury
Mozna by jeszcze dodac sume crc ale by wiecej trwalo (za to pewnosc ze jak podmienisz plik na inny to nie wywali "starej" miniatury)
//Pisane z glowy nie wiem czy zadziala
Użytkownik migajek edytował ten post 01 kwiecień 2005, 16:26
THX - migajek - sprawdze to ale z tym crc to nie taki zly pomysl by jednak jakos musze sie zabezpieczyc przed podmienianiem plikow , zmiana nazw itp ..
A gdybys mogl mi jeszcze podpowiedziec - zeby dodawac rekordy (miniatury ) tylko te np: gdy do juz utworzonego katalogu ( tumba) powiedzmy dorzuce pare tapet - to zeby nie tracic czasu i energi program musial by do juz utworzonego tumba dopisywac tylko te tapety kturych jeszcze nie ma w nim .
No ale najwazniejsze to jak te wszystkie miniatury zapisywac do jednego pliku ?
a tak na marginesie to jak sprawdzac CRC
Witam. No właśnie ja też się spotkałem niedawno z problemem jak zapisać do pliku kilka obrazów i oprócz tego jak nimi w miarę sprawnie zarządzać :). Wtedy to zrodził się mały pomysł aby wykorzystać do tego pliki... INI. No i wszystko było by nawet ok gdyby nie to że, zapisać obraz do takiego pliku można z całkowitą łatwością ale już z odczytem pojawił się straszny problem gdyż standartowo maksymalna długość odczytanego tekstu nie przekracza 2048 znaków co przy nawet sporej kompresji pliku jest długością całkowicie niewystarczającą :). Drugi problem jest taki że jeśli plik ma np. 1MB to po zapisaniu do pliku INI ma już ich 2. Ale wykorzystując kompresje i wielkość 100x100 można przy odczycie ok pięćsetnej pozycji uzyskać czas ok 0.8 do 0.9 sek. gorzej z zapisem na to potrzebowałem do zapisania 500 pozycji (bmp 800x600 kompresja 70%) min 14 sek uzyskując plik 2,3 MB. Dopisywanie kolejnych pozycji przegiegało już dość sprawnie. No a teraz konkrety he he. Oczywiście koło profesjonalizmu to nigdy nie leżało ale może się przyda :).
Zapis do pliku to funkcja:
Index: Pod jaką nazwą zostanie zapisana pozycja Image: nie trzeba tłumaczyć ImageWidth: max szerokość obrazka ImageHeight: max wysokość obrazka CompressQuality: stopień kompresji Stretch: czy obraz ma być dopasowany do zadanej wielkości czy przeskalowany w proporcji function WritePictureJpeg(Index: String; Image: TGraphic; ImageWidth, ImageHeight, CompressQuality: Integer; Stretch: Boolean): Boolean; var TMS: TMemoryStream; Text: String; Ini: TIniFile; Bmp: TBitmap; Jpg: TJpegImage; begin Result:= False; try // Utworzenie obrazów Bmp:= TBitmap.Create; Jpg:= TJpegImage.Create; // Ustalenie rozmiarów obrazka // Jeżeli Stretch jest True if Stretch then begin // Zmiana roziaru obrazka Bmp.Width:= ImageWidth; Bmp.Height:= ImageHeight; end else begin // Jeśli obraz ma być proporcjonalny wtedy przeskaluj if Image.Width >= Image.Height then begin Bmp.Width:= ImageWidth; Bmp.Height:= Ceil((ImageWidth / Image.Width) * Image.Height) end else begin Bmp.Width:= Ceil((ImageHeight / Image.Height) * Image.Width); Bmp.Height:= ImageHeight; end; end; // Pobranie obrazka Bmp.Canvas.StretchDraw(Rect(0, 0, Bmp.Width, Bmp.Height), Image); Jpg.Assign(Bmp); // Kompresja pliku jpg.CompressionQuality:= CompressQuality; Jpg.DibNeeded; Jpg.Compress; // Utworzenie strumienia TMS:= TMemoryStream.Create; // Załadowanie strumienia Jpg.SaveToStream(TMS); // Procedura zamaiany strumienia w tekst TMS.Position:= 0; SetLength(Text, (TMS.Size - TMS.Position) * 2); BinToHex(PChar(Integer(TMS.Memory) + TMS.Position), PChar(Text), TMS.Size - TMS.Position); // Zpisanie do pliku Ini:= TIniFile.Create('C:\Ala\eee.ini'); Ini.WriteString(Index, 'Value', Text); Ini.Free; Result:= True; finally TMS.Free; Bmp.Free; Jpg.Free; end; end; A teraz odczyt: function ReadPictureJpeg(Index: String; Image: TJpegImage): Boolean; var Stream: TMemoryStream; Text: String; ListString: TStringList; Position: Integer; begin Result:= False; { if not (Image is TJpegImage) then Exit; } try Stream:= TMemoryStream.Create; Text:= ''; ListString:= TStringList.Create; // Załadowanie listy ListString.LoadFromFile('C:\Ala\eee.Ini'); // Pobranie tekstu Text:= ListString.Strings[ListString.IndexOf('[' + Index + ']') + 1]; // Usunięcie identyfikatora Delete(Text, 1, 6); // Otrzymany tekst przerabiamy na wartość binarną if Text <> '' then begin Position:= Stream.Position; Stream.SetSize(Stream.Size + Length(Text) div 2); HexToBin(PChar(Text), PChar(Integer(Stream.Memory) + Stream.Position), Length(Text) div 2); Stream.Position := Position; // if Stream <> nil then begin Image.LoadFromStream(Stream); Result:= True; end; end; finally // Zwolnienie zmiennych ListString.Free; Stream.Free; end; end;
Może się nada. Pozdrawiam.
// dodanie codebox
Użytkownik _Herkules_ edytował ten post 02 kwiecień 2005, 11:44
BumaDruma: E... sorry... ale to chyba nie jest najlepszy pomysl.
Helios: o crc masz na 4p,
co do dopisywania : otwierasz plik z miniaturami, po kolei je wyswietlasz (jesli suma crc zapisana w rekordzie jest rowna wyliczonej z konkretnego pliku) jesli nie to nadpisujesz dana miniature, czyli np. przy ladowaniu wszystkie miniatury zapisujesz do tablicy, zmieniasz element o niepasujacym crc i zpisujesz spowrotem - jesli zas pojawily sie nowe pliki to dopisujesz je na koncu.
Użytkownik migajek edytował ten post 02 kwiecień 2005, 09:56
ok THX - BumaDruma -
wszystko fajnie ale chyba jednak sprobuje w inny sposob.
Chcialbym raczej zapisywac do bazy a nie do ini . Ale i tak wiekie THX :)