Kilka Bitmap w jednym pliku!

0

Wie ktoś jak zapisać kilka bitmap w jednym pliku?? Obok każdej bitmapy mają być 2 wartości "integer".

0

O co chodzi? Piszesz, że chcesz zapisać kilka bitmap w jednym pliku a poźniej
piszesz, że chcesz podzielić plik na kilka części.

0

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.

0

Trzeba by się zainteresować strumieniami oraz metodami TBitmap.SaveToStream() oraz TBitmap.LoadFromStream() .

0

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 :)

0

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!.

0

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

0

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

0

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

0
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 ??

0

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.

0

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

0

snw: nie wiedziałem, że Ty takie mądre rzeczy piszesz :) BTW: wrzuć to w znaczniki (alt+d) - będzie czytelniejsze

0

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:

  1. 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

  1. 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 :)

0

No chłopaki popisaliście się 8-0 .
Dzięki bardzo.
Pozdro dla wszystkich [!!!]

1 użytkowników online, w tym zalogowanych: 0, gości: 1