Wie ktoś jak zapisać kilka bitmap w jednym pliku?? Obok każdej bitmapy mają być 2 wartości "integer".
O co chodzi? Piszesz, że chcesz zapisać kilka bitmap w jednym pliku a poźniej
piszesz, że chcesz podzielić plik na kilka części.
Wydaje mi się, że nie istnieją gotowe mechanizmy realizujące taką operację. Musiałbyś, korzystając z nagłówka każdej z bitmap, odczytać ich rozmiary napisać procedurę do ładowania bitmap do pamięci.
Trochę prostszym rozwiązaniem byłoby po uruchomieniu programu zapisywanie każdej z bitmap do pliku tymczasowego .bmp, ładowanie go i usuwanie, ale to rozwiązanie powolne i nieeleganckie.
Trzeba by się zainteresować strumieniami oraz metodami TBitmap.SaveToStream() oraz TBitmap.LoadFromStream() .
Z tego co widze to chcesz zrobic dokladnie to samo co ja :)
Obawiam sie ze tez musze sie zajac strumieniami [sciana]
BTW . jak mi sie uda cos wykombinowac to dam znac :)
Może to komuś pomoże :
Budowa naglowka pliku BMP:
Type
TBitMapHeader =
Record
bfType : Word; (dwa bajty)
bfSize : LongInt; (cztery bajty)
bfReserved : LongInt;
bfOffBits : LongInt;
biSize : LongInt;
biWidth : LongInt;
biHeight : LongInt;
biPlanes : Word;
biBitCount : Word;
biCompression : LongInt;
biSizeImage : LongInt;
biXPelsPerMeter : LongInt;
biYPelsPerMeter : LongInt;
biClrUsed : LongInt;
biClrImportant : LongInt;
End;
Gdzie:
bftype - jest to dwubajtowa sygnatura "BM"
bfsize - czterobajtowy rozmiar pliku
bfreserved - pole zarezerwowane(0)
bfoffbits - przesuniecie poczatku danych graficznych
bisize - podaje rozmiar naglowka
biwidth - wysokosc bitmapy w pikselach
biheight - szerokosc bitmapy w pikselach
biplanes - liczba pitplanow(prawie zawsze ma wartosc 1)
bibitcound ˙- ilosc bitow na piksel. Przyjmuje wartosc 1,4,8 lub 24.
bicompression - sposob kompresji
bisizeimage - rozmiar obrazka w bajtach. W przypadku bitmapy nie
skompresowanej rowne 0.
bixpelspermeter, biypelspermeter - ilosc pikseli na metr
biclrused ˙- ˙ilosc ˙kolorow ˙istniejacej ˙palety, ˙a ˙uzywanych
wlasnie przez bitmape
biclrimporant ˙- okresla ktory kolor bitmapy jest najwazniejszy,
gdy rowny 0 to wszystko sa tak samo istotne.
Następne bajty to obraz palety bmp czytany od tyłu!.
Zależy co chcesz szukać jak chcesz ściagać obrazki "na wyczulca" nie wiedząc jak wygląają to:
wstawiasz
moduł urlmon;
kawałek procedury:
nazwa := edit1.text;
adres := 'http://images.google.pl/images?q='+nazwa+'&hl=pl&lr=&sa=N&tab=wi';
URLDownloadToFile(nil, Pchar(adres), 'c:\plik.tmp', 0, nil);
Terqaz piszesz frazera :) żeby znajdywał linki i zapisaywał dane obrazki w w/w sposób :) jak nie iwesz co to frazer poczytaj o XML'u
LOL
Koleś chce w jednym pliku mieć kilka obrazów, a tu jeden pisze mu nagłówek BMP, drugi tłumaczy jak ściągać z netu... D
Zapisuj do pliku takie pary:
[dlugość obrazka][obrazek][dlugość obrazka][obrazek]........
ewentualnie zapisuj do pliku rekordy a w nich tego typu dane jak długość całego rekordu, obrazek, dodatkowe dane
i odczyt robisz tak:
pomijasz znaną wielkość nagłówka i odczytujesz obraz aż dojdziesz do miejsca, na które wskazuje wartość zapisana przed obrazem - i tak w kółko
tak jak obiecalem, tak i zrobilem :)
Kod jest gotowy, co prawda sluzy on do indkesowania obrazkow z danego katalogu (tzn otwiera obrazek typu bmp/jpg/gif , zmniejsza go do 128x128, konwertuje do jpg i zapisuje wraz ze specjalnym naglowkiem[nazwa pliku, rozmiar a dysku, dlugosc danych miniatury]) a nastepnie odczytuje wczesniej przygotowany plik. Poniewaz jest to tylko przykald zapisu/odczytu, to zamiast miniatury wyswietlac to je zapisuje w podkatalogu. No ale to juz se chyba kazy przerobi wg wlasnego uznania ;)
kod zrodlowy przykladu : http://www.migajek.com/ekspert/indeksowanie_miniatur.rar
Marooned napisał(a)
LOL
Koleś chce w jednym pliku mieć kilka obrazów, a tu jeden pisze mu nagłówek BMP, drugi tłumaczy jak ściągać z netu... D
Jeden pomyślał :) dzięki Marooner
Migajek - dzięki za kod :)
Ale jak zapisać kilka Bitmap do jedengo pliku ??
Można by to zrobić w taki sposób jak pisze Marooned. A więc, zapisujesz rozmiar obrazku w formie powiedzmy rekordu, potem obrazek i tak w kółko. Bitmapa ma dwie metody, które umożliwiają zapis i odczyt, niestety ktoś upchnął je w sekcji Protected. Żeby się do nich dokopać trzeba zadeklarować własny typ np.
TMyBitMap = Class(TBitmap)
End;
Aby się dobrać do tych metod można by zrobić tak: TMyBitMap(JakasBitMapa).WriteData bądź ReadData. Metoda WriteData zapisują obraz do strumienia w pozycji, w której się wcześniej ustawisz. Z tego, co wiem metoda ta przed bitmapa zapisuje najpierw rozmiar, ale nie bardzo jeszcze wiem jak go odczytać, tzn. do wieczora będę wiedział [diabel] Na początku pliku możesz zapisać jakiś nagłówek z sygnaturką i ilością bitmap zapisanych w pliku, żeby sobie życia zbytnio nie komplikować. Jeśli masz opanowane strumienie nie będziesz miał raczej problemów. Reasumując; Tworzysz strumień, zapisujesz sobie rekord z rozmiarem bitmapy, ustawiasz się za tym rekordem i używając TMyBitMap(JakasBitMapa).WriteData zapisujesz obrazek, potem ustawiasz się za bitmapą i powtarzasz tą operacje w kółko aż ci się znudzi.
W chwili obecnej nie mam żadnego przykładu żeby ci to pokazać (partycje się rozsypały), ale jak coś wyklepie to ci podeśle.
dawno temu stworzyłem taki swój format pliku który służył właśnie do przechowywania wielu obrazów graficznych.
nowo powstały plik miał rozszerzenie SND i zawierał w sobie ileś tam plików SNW.
to procedura która zmienia plik BMP w SNW (hehe)
(różnice są w tym że obracam dane dotyczące obrazu, bo w pliku BMP trzeba je normalnie czytać od tyłu, i usuwam zbędne dane nagłówka)
type
TSNWheading = record
exc : string[2];
size : longint;
x : word;
y : word;
end;
TBMPheading = record
picture_type : array[0..1] of char;
file_size : longint;
rezerved_1 : word;
rezerved_2 : word;
distance_to_picture : longint;
info_heading_size : longint;
x : longint;
y : longint;
picture_plans_qantity : word;
bits_per_pixel : word;
kompresion_type : longint;
picture_size : longint;
horizontally_DPI : longint;
vertically_DPI : longint;
colors_used : longint;
colors_meaningfull : longint;
end;
TcolorRGB = record
R : byte;
G : byte;
B : byte;
rezerved : boolean;{jak to dezaktywowac ?(* jeb**y Microsoft *)}
end;
TRGBpalette = array[0..255] of TcolorRGB;
TPH13pattern = ^TRGBpalette;
TH13ScreenTable = array[0..63999] of byte;
TPH13screen = ^TH13ScreenTable;
const {część pewnie jest zbędna}
H13picture : Tpicture = (width:320;height:200;size:64000);
SNWSize = 65035;{heading+palette+picture}
BMPheadingSize = 54;
SNDheadingSize = 15;
SNWheadingSize = 11;
SND_SNWsegSize = SNWSize+SNDheadingSize;{rozmiar segmentu SNW w pliku SND}
H13patternSize = 1024;
PI = 3.14159;
T : boolean = true;
F : boolean = false;
{******************************* BMPtoSNW *********************************}
procedure BMPtoSNW(name : string);
var obrazek : TPH13screen;
color256patterns : TPH13pattern;
plik : file;
licznik, wynik : word;
BMPhead : TBMPheading;
SNWhead : TSNWheading;
P : PathStr;
D : DirStr;
N : NameStr;
E : ExtStr;
begin
assign(plik, name);
reset(plik, 1);
licznik:=BMPheadingSize;
BlockRead(plik, BMPhead, licznik, wynik);
new(color256patterns);
licznik:=H13patternSize;
BlockRead(plik, color256patterns^, licznik, wynik);
getmem(obrazek, BMPhead.y*BMPhead.x);
for licznik:=0 to (BMPhead.y-1) do
BlockRead(plik, obrazek^[((BMPhead.y-1)-licznik)*BMPhead.x], BMPhead.x, wynik);
close(plik);
fsplit(name,D,N,E);
E:='.SNW';
name:=D+N+E;
assign(plik, name);
rewrite(plik,1);
licznik:=H13patternSize;
SNWhead.x:=BMPhead.x;
SNWhead.y:=BMPhead.y;
SNWhead.exc:='SNW';
SNWhead.size:=BMPhead.x*BMPhead.y;
Blockwrite(plik, SNWhead, snwheadingsize, wynik);
Blockwrite(plik, color256patterns^, licznik, wynik);
Blockwrite(plik, obrazek^, SNWhead.size, wynik);
freemem(obrazek,BMPhead.y*BMPhead.x);
dispose(color256patterns);
close(plik);
end;{BMPtoSNW}
tutaj procedure która z plików SNW tworzy archiwum SND
{******************************* CreateSND *********************************}
procedure CreateSND(path : string);
var
info : TSNDheading;
plik, dane : file;
DirInfo : SearchRec;
Archive : Word;
P : PathStr;
D : DirStr;
N : NameStr;
E : ExtStr;
licznik, wynik : word;
obrazek : TPH13screen;
paleta : TPH13pattern;
numer : longint;
pozycja : real;
attr : word;
key : char;
snwhead : Tsnwheading;
begin
attr:=0;
clrscr;
getmem(obrazek,H13picture.size);
new(paleta);
Assign(plik,path+'data.snd');
rewrite(plik,1);
FindFirst(path+'*.*',Archive,DirInfo);
if DosError = 0 then
begin
writeln('Creating headings...');
while DosError = 0 do
begin
if (DirInfo.Name<>'DATA.SND')and(DirInfo.Name<>'.')and(DirInfo.Name<>'..') then
begin
GetFAttr(dane, Attr);
if Attr and ReadOnly<> 0 then
begin
Writeln(DirInfo.Name,' is read only file !');
writeln('Set ',DirInfo.Name,' as a r/w file and continue ?');
writeln(' [Y/N]');
key:=readkey;
if (key='N') or (key='n') then
begin
erase(plik);
halt;
end
else
setfattr(dane,$20);
end;
assign(dane,path+DirInfo.Name);
writeln('-',DirInfo.Name,' heading...');
reset(dane,1);
licznik:=SNDheadingSize;
BlockWrite(plik, info, licznik, wynik);
delay(1);
close(dane);
end;
FindNext(DirInfo);
end;
writeln('Creating complete.');
writeln('');
end
else
begin
writeln('This directory is empty.');
erase(plik);
end;
E:='.SNW';
numer:=0;
FindFirst(path+'*.*',Archive,DirInfo);
if DosError = 0 then
begin
while DosError = 0 do
begin
fsplit(path+DirInfo.Name,D,N,E);
if DirInfo.Name<>'DATA.SND' then
begin
if E='.SNW' then
begin
assign(dane,path+DirInfo.Name);
reset(dane,1);
licznik:=SNWheadingSize;
blockread(dane,SNWhead,licznik, wynik);
writeln('-',DirInfo.Name);
pozycja:=filepos(plik);
writeln('Filling heading...');
writeln(' exc:',E);
writeln(' adres:',pozycja:0:0);
writeln(' x:',snwhead.x);
writeln(' y:',snwhead.y);
writeln(' size:',snwhead.y*snwhead.x);
seek(plik,numer*SNDheadingSize);
info.exc:=E;
info.adres:=round(pozycja);
info.size:=snwhead.y*snwhead.x;
info.x:=snwhead.x;
info.y:=snwhead.y;
licznik:=SNDheadingSize;
blockwrite(plik,info,licznik,wynik);
seek(plik,round(pozycja));
write('Moving data...',filepos(plik));
licznik:=H13patternSize;
blockread(dane,paleta^,licznik , wynik);
BlockWrite(plik, paleta^, licznik, wynik);
for licznik:=0 to (snwhead.y-1) do
blockread(dane, obrazek^[licznik*snwhead.x], snwhead.x, wynik);
for licznik:=0 to (snwhead.y-1) do
blockwrite(plik, obrazek^[licznik*snwhead.x], snwhead.x, wynik);
writeln('-',filepos(plik));
delay(1);
close(dane);
inc(numer);
end;
end;
FindNext(DirInfo);
end;
writeln('...');
writeln('SUCCES');
end;
close(plik);
freemem(obrazek,snwhead.x*snwhead.y);
dispose(paleta);
end;{CreateSND}
tutaj dwie procedury wczytujące
{****************************** LoadSND_SNWh13 ****************************}
procedure LoadSND_SNWh13(var pic : TPH13screen; name : string; numer : real;make : boolean);
var snd : file;
wynik : word;
info : TSNDheading;
begin
if make then
new(pic);
assign(snd, name);
reset(snd, 1);
seek(snd,round(numer*SNDheadingSize));
blockread(snd, info, sndheadingsize, wynik);
seek(snd,info.adres+H13patternSize);
blockread(snd, pic^, H13picture.size, wynik);
close(snd);
end;{LoadSND_SNWh13}
{do poprawki - pic:TPscreen !!!}
{************************** LoadSND_SNWh13_PS ******************************}
procedure LoadSND_SNWh13_PS(var pic : Tpscreen; name : string; numer : real;make : boolean);
var snd : file;
wynik : word;
info : TSNDheading;
begin
assign(snd, name);
reset(snd, 1);
seek(snd,round(numer*SNDheadingSize));
blockread(snd, info, sndheadingsize, wynik);
seek(snd,info.adres+H13patternSize);
if make then
getmem(pic,info.x*info.y);
blockread(snd, pic^, info.x*info.y, wynik);
close(snd);
end;{LoadSND_SNWh13_PS}
może to coś pomoże. z serwisu na powyższy kod się wypisuję ponieważ powstał lata temu, natomiast gwarantuję że działa :). problem w tym że to było pisane pod pascala i pod tryb h13 więc na pewno trzeba coś zmienić (część stałych, rozmiar palety). np pierwsza procedura czytająca działa tylko dla bitmap o rozmiarze ekranu w tym trybie (druga już np dla wszystkich). ale idea jest ta sama. aha, plik SND stworzony jest w ten sposób, że najpierw są adresy wszystkich plików wewnątrz, a potem ciurkiem dane</delphi>
EDIT=znacznik, literówki itp
snw: nie wiedziałem, że Ty takie mądre rzeczy piszesz :) BTW: wrzuć to w znaczniki (alt+d) - będzie czytelniejsze
hehe, ale Wy se lubicie życie utrudniać :)
Ja bym zrobił to tak(może i trochę lamerskie, ale najprostsze).
Wszystkie bitmapy do jednego pliku - zasoby!!
Dalej są dwie możliwości:
- Tworzymy 2 pliki tekstowe. W jednym będą nazwy bitmap, a w drugim te integery, np:
---------Plik1.txt--------
bitmapa1
bitmapa2
bitmapa3
---------Plik2.txt--------
12 15
182 365
349 657
- Druga możliwość taka, że tworzymy jeden plik typowany zamiast tych dwóch:
type
TPlik = record
nazwa: string[255];
liczba: integer
end;
var
plik: file of TPlik
rplik: TPlik;
Reszta to chyba wiadomo :)
No chłopaki popisaliście się 8-0 .
Dzięki bardzo.
Pozdro dla wszystkich [!!!]