Προς το περιεχόμενο

Πως να φορτώσω βιβλιοθήκη στην C++ Builder 6


Paytor

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλημέρα

Μία ερώτηση.Θέλω να φορτώσω την βιβλιοθήκη FreeImage στην C++ για να μπορώ να φορτώσω κάποια έδη εικόνας που χρειάζομαι για το project μου όπως(gif,jpeg,tiff,png).Κάνω project->Import Type Library και μετα add το αρχείο που θέλω(dll,lib) αλλα μου βγάζει σφάλμα οταν πάω να την φορτώσω.Προσπάθησα επίσης με την εντολη implib myName.lib myName.dll και πάλι είχα πρόβλημα.Το ίδιο έκανα και με την coff2omf myName.lib myName.~lib, όπου δημιούργησε ενα αρχέιο lib το οποίο και έκανα insert στο project1.exe και include μετα στο unit1,έβγαλε και το header file στο unit1 και έκανε compile χωρίς σφάλμα αλλα οταν δοκίμασα να φορτώσω εικόνα δεν την φόρτωσε(unknown file format .gif).Τι κάνω λάθος???Οποιαδήποτε ιδέα είναι καλοδεχούμενη!!!

Ευχαριστώ!!!

Δημοσ.

Καταρχήν χρησιμοποιώ (ορισμένες φορές) την FreeImage 3.7.0.

 

Για να κάνω import το FreeImage.dll χρησιμοποιώ την εντολή implib -a freeimage.lib freeimage.dll ύστερα αντιγράφω το lib το dll και το h στον κατάλογο του project μου. Προσθέτω στα αρχεία του Project το lib και δηλώνω κανονικά το h στο unit που με ενδιαφέρει.

 

Για να φορτώσεις μια εικόνα μέσο της FreeImage Library πρέπει να ακολουθήσεις τα παρακάτω βήματα:

 

1ον) Καλείς την εντολή FreeImage_Initialise(TRUE) ώστε να ενεργοποιηθεί η FreeImage DLL. Η παράμετρος TRUE απλά εξασφαλίζει ότι η FreeImage δεν θα δοκιμάσει να φορτώσει κανένα εξωτερικό plug-in αρκούμενη στα format αρχείων που η ίδια υποστηρίζει.

 

2ον) Καλείς την εντολή FreeImage_GetFileType(char*) η οποία επιστρέφει για το αρχείο char* τον τύπο του αρχείου εικόνας που πρόκειται να φορτώσεις σε μια μεταβλητή FREE_IMAGE_FORMAT. Εάν το αρχείο είναι άγνωστο τότε επιστρέφει FIF_UNKNOWN. Αυτή η ρουτίνα θέλει προσοχή διότι δεν ανιχνεύει ορισμένα «εξωτικά» αρχεία όπως τα WBMP όμως παραμένει η πιο εύκολη μέθοδος που προσφέρει η FreeImage για αυτή την δουλεία.

 

3ον) Καλείς την εντολή FreeImage_Load(FREE_IMAGE_FORMAT,char*) η οποία με βάση τον τύπο του αρχείου εικόνας (FREE_IMAGE_FORMAT) που έχουμε ήδη βρει από την FreeImage_GetFileType φορτώνει το char* και επιστρέφει μια δομή FIBITMAP*.

 

Ως εδώ η FreeImage έχει φορτώσει την εικόνα που θες στην μνήμη, τώρα πρέπει να την παρουσιάσεις σε κάποιο Device Context (DC) στην περίπτωση μας πρόκειται για το TImage control της VCL.

 

4ον) Με την βοήθεια των εντολών FreeImage_GetWidth και FreeImage_GetHeight ρυθμίζεις το client μέγεθος του TImage control ώστε να χωρά ολόκληρη την εικόνα.

 

5ον) Με τις ίδιες εντολές ρυθμίζεις το μέγεθος του εσωτερικού Bitmap που υλοποιεί το TImage control.

 

6ον) Με την βοήθεια της εντολής FreeImage_GetBPP ρυθμίζεις τα Bits-Per-Pixel (βάθος) του TImage Bitmap. Εδώ θέλει λίγη προσοχή διότι η VCL υποστηρίζει εικόνες ως 32bpp ενώ η FreeImage ως 128bpp οπότε για εικόνες με bpp από 64 και πάνω ορίζουμε το Timage Bitmap bpp ως pfCustom και «ότι βγει»..

 

7ον) Τέλος καλούμε την ρουτίνα SetDIBits η οποία με την βοήθεια των εντολών FreeImage_GetHeight, FreeImage_GetBits, FreeImage_GetInfo σχεδιάζει τα pixels της φορτωμένης εικόνας στο TImage control. Τούτη η ρουτίνα δεν καλύπτεται από το PDF βοήθειας της FreeImage διότι είναι ρουτίνα του λειτουργικού.

 

8ον) Αποδεσμεύουμε κάθε δεσμευμένο πόρο (το ίδιο συμβαίνει και αν υπάρχει οπουδήποτε λάθος), με τις εντολές FreeImage_Unload, FreeImage_DeInitialise.

 

Όλα τα παραπάνω βήματα ακολουθούνται από την ρουτίνα FI_Load η οποία φορτώνει με την βοήθεια της FreeImage εικόνες σε ένα TImage control.

Σε περίπτωση σφάλματος παρουσιάζει μήνυμα λάθους και επιστρέφει false διαφορετικά true -φυσικά μπορεί να υπάρχουν bugs ή άλλες αβλεψίες, αλλά σίγουρα θα βοηθήσει όσους θέλουν να ασχοληθούν με την FreeImage..

 

Η βιβλιοθήκη παρέχει και άλλες ρουτίνες φορτώματος, αποθήκευσης και εντοπισμού δεδομένων πολύ πιο ισχυρές αλλά ταυτόχρονα πολύπλοκες

 

>
bool  FI_Load(AnsiString asFilename,TImage *ptrControl)
{
  // FI_Load function (c) DIRECTX
  FIBITMAP             *fiBMP      =  NULL;
  FREE_IMAGE_FORMAT     fiIF       =  FIF_UNKNOWN;
  bool                  bSuccess   =  false;

  try
   {
     try
      {
        // File exists?
        if(!FileExists(asFilename))
         throw   Exception("File not found!");

        FreeImage_Initialise(TRUE);

        // Let Freeimage detect asFilename image format (BMP? GIF? JPEG? PNG? etc)
        if((fiIF=FreeImage_GetFileType(asFilename.c_str(),0))==FIF_UNKNOWN)
         throw   Exception("Unknown file format!");

        // Load image to memory
        if((fiBMP=FreeImage_Load(fiIF,asFilename.c_str(),0))==NULL)
         throw   Exception("Image load failed!");

        // Set ptrControl (Control) to loaded image defaults
        ptrControl->ClientHeight   =  FreeImage_GetHeight(fiBMP);
        ptrControl->ClientWidth    =  FreeImage_GetWidth(fiBMP);

        // Setup TImage->Picture->Bitmap portion with FreeImage data
        ptrControl->Picture->Bitmap->Height       =  FreeImage_GetHeight(fiBMP);
        ptrControl->Picture->Bitmap->Width        =  FreeImage_GetWidth(fiBMP);

        switch(FreeImage_GetBPP(fiBMP))
         {
           case  1: ptrControl->Picture->Bitmap->PixelFormat=pf1bit;  break;
           case  4: ptrControl->Picture->Bitmap->PixelFormat=pf4bit;  break;
           case  8: ptrControl->Picture->Bitmap->PixelFormat=pf8bit;  break;
           case 16: ptrControl->Picture->Bitmap->PixelFormat=pf16bit; break;
           case 24: ptrControl->Picture->Bitmap->PixelFormat=pf24bit; break;
           case 32: ptrControl->Picture->Bitmap->PixelFormat=pf32bit; break;
           // -> No TPixelFormat for 64 & 128 BPP!
           default: ptrControl->Picture->Bitmap->PixelFormat=pfCustom;break;
         }

        // Draw FreeImage on VCL control..
        if(!SetDIBits(ptrControl->Picture->Bitmap->Canvas->Handle,
                      ptrControl->Picture->Bitmap->Handle,
                      0,
                      FreeImage_GetHeight(fiBMP),
                      FreeImage_GetBits(fiBMP),
                      FreeImage_GetInfo(fiBMP),
                      DIB_RGB_COLORS))
         throw   Exception("SetDIBits failed!");

        bSuccess =  true;
      }
     catch(Exception &Error)
      {
        // Ooops! error
        MessageBeep(MB_ICONSTOP);
        Application->MessageBox(Error.Message.c_str(),NULL,MB_ICONSTOP);
      }
   }
  __finally
   {
     // Free any reserved resource
     FreeImage_Unload(fiBMP);
     FreeImage_DeInitialise();
   }

  return   bSuccess;
}

 

Καλή συνέχεια

:)

  • 6 μήνες μετά...
Δημοσ.

Αυτές τις μέρες καθώς αναζητούσα έναν τρόπο να φορτώνω GIF αρχεία κατευθείαν σε ένα TImage component, πράγμα που δυστυχώς δεν υποστηρίζεται άμεσα από το control και μη θέλοντας λόγο μεγέθους να συμπεριλάβω στο λογισμικό μου κάποια εξωτερική βιβλιοθήκη γραφικών (πχ. FreeImage) ή κάποιο Component τρίτου κατασκευαστή, εντόπισα σε αυτή την σελίδα http:// http://www.swissdelphicenter.ch/torry/showcode.php?id=2012 μια μέθοδο (γραμμένη σε Delphi) φορτώματος GIF αρχείων σχεδόν κατευθείαν στα γραφικά components της VCL βασιζόμενη στην χρήση της TOleGraphic class η οποία με την σειρά της βασίζεται στην βιβλιοθήκη της Microsoft, OLEPRO32.DLL η οποία υλοποιεί το OLE (COM) IPicture interface με το οποίο κάθε χειριστής της μπορεί να φορτώσει εύκολα BMPs, JPGs, GIFs, ICOs και WMFs (από ότι είδα σε άρθρο του MSDN http:// http://msdn.microsoft.com/msdnmag/issues/01/10/c/default.aspx ψάχνοντας λίγο παραπάνω την υπόθεση).

 

Επειδή είμαι σίγουρος πως πολύ κόσμος ασχολούμενος με την Delphi ή τον C/C++ Builder κατά καιρούς θα έχει δοκιμάσει διάφορες λύσεις για το φόρτωμα GIF αποφάσισα να δημοσιεύσω ένα μικρό function γραμμένο σε C/C++ Builder 6.0 το οποίο βασιζόμενο στο TOleGraphic επιτρέπει το φόρτωμα ενός GIF και την έξοδο του ως ένα απλό 16bit (διαφορετικά δεν δουλεύει σωστά η απόδοση χρωμάτων σε DIB) Graphics::TBitmap που εύκολα μπορεί να χρησιμοποιηθεί σε VCL components.

 

Φυσικά, ο κώδικας μπορεί να περιέχει λάθει (δοκιμάσθηκε πάντως με στατικά GIF των 2,4,8,16,32,256 χρωμάτων) ενώ όπως καταλαβαίνετε δεν υποστηρίζει GIF animation, τέλος σε περίπτωση απλών transparent GIFs όπου το διάφανο χρώμα περικλείει την εικόνα μπορείτε να χρησιμοποιήσετε το αυτόματο Transparent property των VCL components, διαφορετικά, σε περίπτωση αντίστροφου transparency, όπου το διάφανο χρώμα είναι διαφορετικό από εκείνο που περικλείει την εικόνα, θα πρέπει να το καθορίσετε μόνοι σας (δείτε το TransparentColor property).

 

>
Graphics::TBitmap *LoadGIF(AnsiString strFilename)
{
  // LoadGIF(AnsiString strFilename) for C/C++ Builder 6.0 (c) 2007 Directx.
  Graphics::TBitmap *bmpGIF     =  NULL;
  TFileStream       *Stream     =  NULL;
  TOleGraphic       *oleGraphic =  NULL;

  try
   {
     /* Prepare classes, use TFileStream to load GIF picture into oleGraphic
        (OLE IPicture container)
     */
     Stream      =  new TFileStream(strFilename,fmOpenRead);
     oleGraphic  =  new TOleGraphic();
     oleGraphic->LoadFromStream(Stream);

     /* Prepare a new Graphics::TBitmap class, then draw oleGraphic
        on it's TCanvas (GIF->BITMAP).
     */
     bmpGIF               =  new Graphics::TBitmap();
     bmpGIF->Width        =  oleGraphic->Width;
     bmpGIF->Height       =  oleGraphic->Height;
     bmpGIF->PixelFormat  =  pf16bit;  // Hi-Color to support DIB (even if GIF are up to 256c)
     bmpGIF->HandleType   =  bmDIB; // else (on pf8bit or less) set to DDB
     bmpGIF->Palette      =  oleGraphic->Palette;
     bmpGIF->Canvas->Draw(0,0,oleGraphic);
   }
  __finally
   {
     // Free function resources
     delete   Stream;
     delete   oleGraphic;
   }

  // Return Graphics::TBitmap*
  return   bmpGIF;
}

 

Υπόδειγμα κλήσης (παρουσίαση GIF στο TImage, Image1 component).

>
  Graphics::TBitmap *bmpPicture = NULL;

  try
   {
     bmpPicture = LoadGIF("test.gif");
     Image1->Picture->Assign(bmpPicture);
   }
  __finally
   { delete bmpPicture; }

 

Υ.Γ.

Παρʼ όλο που, όπως έγραψα, το IPicture COM σύμφωνα με το MSDN μπορεί να φορτώσει και άλλα format εικόνων, εντούτοις όλα πλην πάντα του GIF, υποστηρίζονται από την VCL οπότε η χρήση του με αυτά δεν νομίζω ότι προσφέρει κάτι παραπάνω.

Δημοσ.

Κάπου σε μια βιβλιοθήκη του Delphi υπάρχει και ένα TJpgImage ή κάτι τέτοιο, που διαβάζει άμεσα jpg. Δεν υπάρχει πουθενά στο help, αλλά υπάρχει σαν unit από την έκδοση 7 ή και παλιότερα...

Δημοσ.

Πρόκειται για το jpeg.hpp (C/C++ Builder 6, BDS 2006, Turbo C++ Explorer) το οποίο παρέχει τα TJPEGImage και TJPEGData classes για την πλήρη διαχείριση εικόνων JPEG μέσο VCL.

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...