ScanLine für unterschiedliche Farbtiefen



  • Was hast Du gegen 'SaveToFile' ??? Damit ist Dir alles abgenommen.

    Sonst schau mal in WinAPI- Forum. Du kannst Header selber erstellen. Aber wozu?

    Oder zielst du auf Deinen anderen Thread - Text 6 Bild?
    dann sch Dich mal schlau mit SaveToStream! Damit kannste Bilder + Texte + WasWasI in EINE Datei schreiben.



  • Ich möchte mehrere bmp´s in einer Datei speichern, und zusätzlich noch ander Stringdaten.

    Beim Auslesen der gesamten Datei einsteht dan ein vector<stuktur> mit Bitmaps und Bildbeschreibungen.

    Aber mit TStreams kann ich immer nur überschreiben.
    Ich hab noch nicht herausgefunden, wie ich Stück für Stück Daten anhängen kann.



  • Dann Mach das mit Stream!

    Du musst Dir nur ein eigenes 'Formar' ausdenken - oser googeln, ob's sowas gibt.
    Ich mach das So:
    0. Stream öffnen (Leer, Pointer auf Anfang)
    1. Kennung in Stream, wieviel Bytes kommen plus 'Text' für Formatkennung
    2. Daten (genau die Menge) in den Stream schreiben (SaveToStream)
    3. wiederholen 1. und 2. bis alle Daten drin sind
    4. Stream schliessen.
    Volia

    Beim lesen musst Du nur :
    0. Stream öfnnen
    1. Kennung lesen
    2. Daten passend dazu lesen
    3. wiederholen, bis Stream leer ist.
    4. Stream schliessen

    Bei BMPs geht das noch einfacher.
    Aber so kannst Du verschiedene Daten speichern. Ich mach das mit ner Dia- Show-Datei, die enthält bmp, JPG oder GIF ...

    Beim Lesen hts ds Problem, dass jpgs nach lesen den Stream ans Ende setzen!!!
    Dazu kopiere ich die Bytes in einen MemStream und lass daraus lesen.



  • Was meinst Du mit Kennung?
    Size?
    Wie füllst Du das Stream weiter auf mit CopyFrom oder Read?



  • OK Ich habs

    TMemoryStream *stre1 = new TMemoryStream();
        stre1->LoadFromFile("bits/buchlogo1.bmp");
        TMemoryStream *stre2 = new TMemoryStream();
        stre2->LoadFromFile("bits/buchlogo2.bmp");
        TMemoryStream *stre3 = new TMemoryStream();
    
        int s1 = stre1->Size;
        int s2 = stre2->Size;
        stre3->Position = 0;
        stre3->Size = stre1->Size + stre2->Size;
        stre1->SaveToStream(stre3);
        stre3->Position = s1;
        stre2->SaveToStream(stre3);
    
        stre3->SaveToFile("__1.bmp");
        delete stre1;
        delete stre2;
        delete stre3;
    

    Hab den ganzen Tag damit verbracht

    Danke Dir



  • So hatte ich das zwar nicht gemeint, aber wenns geht.

    Ich Lade die Bilder (nacheinander ) in ein TPicture - da ist egal, welches Format - und schreibe die mit extra Daten in eine Datei.

    Ich mach EINEN Stream auf (FileStream)

    Ich schreibe ein paar BINAERDATEN in den Stream:
    - Datenmenge - Groese der Bilddaten + ein paar extra bytes
    - die extra bytes sind z.b: Bildtyp (JPEG,GIF ...)

    Dann mit SaveToStream das Picture in den Stream

    Dann das ganze widerholt mit dem naechsten Bild.

    Am Ende Stream schliessen.

    Z.B. so:

    I1, I2 und I3 sind TImage- Objekte im Formular. In alle drei ist irgendein Bild geladen!
    Die Bilder können GIF, JPEG oder BMPs sein.

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Fuer jpeg muss natuerlich jpeg.h includiert sein
    Fuer GIF hab ich GIFIMAGE im System!
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    void __fastcall TForm1::M_Save_1_2Click(TObject *Sender)
    {
      ShortString ClassName;
      unsigned char ClassNameSize;
      long Size;
      TFileStream *FS=new TFileStream("D:\\M_Test.SHP",fmCreate);
      TMemoryStream *MS=new TMemoryStream();
      ClassName=I1->Picture->Graphic->ClassName();
      ClassNameSize=ClassName[0];
      I1->Picture->Graphic->SaveToStream(MS);
      Size=MS->Size;
      FS->Write(&Size,sizeof(Size));
      FS->Write(&ClassName,ClassNameSize+1);
      FS->CopyFrom(MS,0);//Size);
      MS->Size=0;
      ClassName=I2->Picture->Graphic->ClassName();
      ClassNameSize=ClassName[0];
      I2->Picture->Graphic->SaveToStream(MS);
      Size=MS->Size;
      FS->Write(&Size,sizeof(Size));
      FS->Write(&ClassName,ClassNameSize+1);
      FS->CopyFrom(MS,0);//Size);
      MS->Size=0;
      ClassName=I3->Picture->Graphic->ClassName();
      ClassNameSize=ClassName[0];
      I3->Picture->Graphic->SaveToStream(MS);
      Size=MS->Size;
      FS->Write(&Size,sizeof(Size));
      FS->Write(&ClassName,ClassNameSize+1);
      FS->CopyFrom(MS,0);//Size);
    
      delete MS;
      delete FS;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::M_LoadClick(TObject *Sender)
    {
      Graphics::TBitmap *BM;
      TJPEGImage *JPG;
      TGIFImage *GIF;
    
      AnsiString ClassName;
      unsigned char ClassNameSize;
      char ClassNameChar[256];
      long Size;
      TFileStream *FS=new TFileStream("D:\\M_Test.SHP",fmOpenRead	);
      TMemoryStream *MS=new TMemoryStream();
      FS->Read(&Size,sizeof(Size));
      FS->Read(&ClassNameSize,sizeof(ClassNameSize));
      FS->Read(ClassNameChar,ClassNameSize);
      ClassNameChar[ClassNameSize]=0;
      ClassName=AnsiString(ClassNameChar);
      MS->CopyFrom(FS,Size);
      MS->Position=0;
      if (ClassName.AnsiCompareIC("TBitmap")==0)
      {
        BM=new Graphics::TBitmap();
        I3->Picture->Assign(BM);
        delete BM;
      }
      if (ClassName.AnsiCompareIC("TJPEGImage")==0)
      {
        JPG=new TJPEGImage();
        I3->Picture->Assign(JPG);
        delete JPG;
      }
      if (ClassName.AnsiCompareIC("TGIFImage")==0)
      {
        GIF=new TGIFImage();
        I3->Picture->Assign(GIF);
        delete GIF;
      }
      I3->Picture->Graphic->LoadFromStream(MS);
      MS->Size=0;
      FS->Read(&Size,sizeof(Size));
      FS->Read(&ClassNameSize,sizeof(ClassNameSize));
      FS->Read(ClassNameChar,ClassNameSize);
      ClassNameChar[ClassNameSize]=0;
      ClassName=AnsiString(ClassNameChar);
      MS->CopyFrom(FS,Size);
      MS->Position=0;
      if (ClassName.AnsiCompareIC("TBitmap")==0)
      {
        BM=new Graphics::TBitmap();
        I1->Picture->Assign(BM);
        delete BM;
      }
      if (ClassName.AnsiCompareIC("TJPEGImage")==0)
      {
        JPG=new TJPEGImage();
        I1->Picture->Assign(JPG);
        delete JPG;
      }
      if (ClassName.AnsiCompareIC("TGIFImage")==0)
      {
        GIF=new TGIFImage();
        I1->Picture->Assign(GIF);
        delete GIF;
      }
      I1->Picture->Graphic->LoadFromStream(MS);
      MS->Size=0;
      FS->Read(&Size,sizeof(Size));
      FS->Read(&ClassNameSize,sizeof(ClassNameSize));
      FS->Read(ClassNameChar,ClassNameSize);
      ClassNameChar[ClassNameSize]=0;
      ClassName=AnsiString(ClassNameChar);
      MS->CopyFrom(FS,Size);
      MS->Position=0;
      if (ClassName.AnsiCompareIC("TBitmap")==0)
      {
        BM=new Graphics::TBitmap();
        I2->Picture->Assign(BM);
        delete BM;
      }
      if (ClassName.AnsiCompareIC("TJPEGImage")==0)
      {
        JPG=new TJPEGImage();
        I2->Picture->Assign(JPG);
        delete JPG;
      }
      if (ClassName.AnsiCompareIC("TGIFImage")==0)
      {
        GIF=new TGIFImage();
        I2->Picture->Assign(GIF);
        delete GIF;
      }
      I2->Picture->Graphic->LoadFromStream(MS);
      MS->Size=0;
    
      delete MS;
      delete FS;
    }
    

    In der Datei stehen dann nacheinander:
    Menge der folgenden Bild- Bytes
    Laenge des Kennstrings
    Kennstring
    Bytes des Bildes

    Menge folgende ....

    Genau andersrum kann das ausgelesen werden!
    Du kannst auch ganz andere Daten einmischen - mit geeigneter Kennung + Size- Angabe!



  • Es is supereinfach

    Erst Text und paar bitmaps speichern

    TMemoryStream *stre1 = new TMemoryStream();
        TStrings *lt = new TStringList;
        TMemoryStream *stre2 = new TMemoryStream();
    
        stre2->Position = 0;
        lt->Text = "Hier sin meine ganzen texteABJETZTFOLGTALLESANDERE";
        stre2->Size = lt->Count + stre2->Size;
        lt->SaveToStream(stre2);
    
        stre1->LoadFromFile("bits/linus.bmp");
        stre2->Size = stre1->Size + stre2->Size;
        stre1->SaveToStream(stre2);
    
        stre1->LoadFromFile("bits/buchlogo2.bmp");
        stre2->Size = stre1->Size + stre2->Size;
        stre1->SaveToStream(stre2);
    
        stre2->SaveToFile("__1.mydc");
        delete stre1;
        delete stre2;
        delete lt;
    

    Datei wider laden

    TStrings *nlst = new TStringList;
        nlst->LoadFromFile("__1.mydc");
        //Vor stringposition ABJETZTFOLGTALLESANDERE
        //sind meine ganzen strings und zuweisungen gespeichert
        int pos = nlst->Text.Pos("ABJETZTFOLGTALLESANDERE");
        AnsiString as = nlst->Text.SubString(1, pos-1);
        delete nlst;
        ShowMessage(as);
        //AnsiString as verarbeiten
    
        //danach nur noch bmp für bmp laden
        TMemoryStream *stre3 = new TMemoryStream();
        stre3->LoadFromFile("__1.mydc");
        stre3->Position = pos+24;//die 24 entspricht der size die für
                                 //ABJETZTFOLGTALLESANDERE
                                 //hochgezählt wird
        while(pos < stre3->Size){
            Image1->Picture->Bitmap->LoadFromStream(stre3);
            //eigentlich werden die bitmaps aber woanders abgespeichert
            pos = stre3->Position;
        }
    
        delete stre3;
    


  • Hi,
    evtl. wäre es besser das I1, I2 und I3 vorher in ein Array zu packen. Dann kann man das schon mit einer for Schleife regeln und es wird kürzer (keine Wiederholungen) und variabler.

    MfG

    Alexander Sulfrian



  • Die Funktion wird wohl in einer schleife aufgerufen, nehme ich an.

    Oder eher doch nich



  • Das war nur in Beispiel!
    Sollte nur das Speichern mehrerer Bilder zeigen

    War zu faul eine Schleife zu machen!


Anmelden zum Antworten