Menu

problems with writing files.

Developers
Anonymous
2003-06-24
2003-09-09
  • Anonymous

    Anonymous - 2003-06-24

    Hi!

    I downloaded FreeImage, compiled it, linked it, and integrated the functions into my app fine, and the file reading functions are working great. I just can't get the file writing functions to work right, and I was wondering if someone can check my code.

    It's C not C++, no MFC, and I'm using the new VS 2003.

    it's rather straight-forward, and it worked fine with my own functions that wrote BMP and TGA before I added FreeImage, but I realy need the PNG support.

    case ID_EXPORT:
      strcpy(exportfilename,GetFileName(hwnd,true));
      strlwr(exportfilename);
      if(strcmp(exportfilename,"")>0)
      {
        SetCursor(LoadCursor(NULL,IDC_WAIT));

        hdc=GetDC(hwnd);
        exporthdc=CreateCompatibleDC(hdc);
        exporthbm=CreateCompatibleBitmap(hdc,finalclock.pixelsize,finalclock.pixelsize);
        ReleaseDC(hwnd,hdc);
       
        SetStretchBltMode(exporthdc,WHITEONBLACK);
        SelectObject(exporthdc,exporthbm);
        drawclock(exporthdc,finalclock.pixelsize,finalclock.pixelsize,finalclock);

        // ........................... export a Freeimage
        if(exporthbm)
        {
          GetObject(exporthbm, sizeof(BITMAP), (LPSTR) &exportbmp);
          exportinfo=CreateBitmapInfoStructure(exportbmp);
          dib=FreeImage_Allocate(exportbmp.bmWidth, exportbmp.bmHeight,
                                 exportbmp.bmBitsPixel,
                                 0xFF000000,0x00FF0000,0x0000FF00);
          hdc=GetDC(hwnd);
          GetDIBits(hdc, exporthbm, 0, exportbmp.bmHeight,
                    dib, exportinfo, DIB_RGB_COLORS);
          ReleaseDC(hwnd,hdc);
                     
          if(strstr(exportfilename,".png")!=NULL)
          {
            FreeImage_Save(FIF_PNG, dib, exportfilename, 0);
          }
          else if(strstr(exportfilename,".jpg")!=NULL)
          {
            FreeImage_Save(FIF_JPEG, dib, exportfilename, JPEG_QUALITYSUPERB);
          }
          else if(strstr(exportfilename,".bmp")!=NULL)
          {
            FreeImage_Save(FIF_BMP, dib, exportfilename, 0);
          }
          else if(strstr(exportfilename,".tga")!=NULL)
          {
            FreeImage_Save(FIF_TARGA, dib, exportfilename, 0);
          }
          else
          {
            FreeImage_Save(FIF_UNKNOWN, dib, exportfilename, 0);
          }
          FreeImage_Unload(dib);
        }

        MessageBox(NULL, "Your Graphic was saved!","Done!",MB_OK | MB_ICONINFORMATION);
        DeleteDC(exporthdc);
        DeleteObject(exporthbm);
        exporthbm=(HBITMAP)NULL;

        SetCursor(LoadCursor(NULL,IDC_ARROW));
      }
      InvalidateRect(hwnd,NULL,false);
      UpdateWindow(hwnd);
      break;

     
    • Anonymous

      Anonymous - 2003-06-24

      BTW- it writes the header info for the files, but the bitmap sections are blank.

      and smaller question- is there an easier way to indicate the file format based on the file name, rather than passing the FIF values?

       
    • Hervé Drolon

      Hervé Drolon - 2003-06-24

      See the FAQ (section "How do I convert a HBITMAP to a FreeImage image") to see how to use the GetDIBits function. Also, do not call FreeImage_Save with the FIF_UNKNOWN parameter !
      About a generic reader / writer using filenames instead of FIF formats, see the generic sample named "batchload" distributed with the binary and source distribution.

      Herv

       
      • Anonymous

        Anonymous - 2003-06-24

        I did check the FAQ first- and that code did not work.

        (it also had an error in the name of the dib variable, but that error is not there now- did you just fix it?
        also, if you just remove the :: on the getDC and releaseDC statements, it will be C code. )

        I got to the point I am now (in the code above) by trying to get that code to work.

        As I said, the reading files section of my program is working just fine, based on the code from the FAQ, but the writing is not.

        I will take a look at the batchload demo- I did not look at the demos, just the FAQ and the PDF.

         
    • Anonymous

      Anonymous - 2003-06-24

      One more thing- I was kind of hoping that by passing FIF_UNKNOWN to FreeImage_Save, that the function would check the extension of the filename to find out the format to use.

      Can I recomend that for the next version?

       
    • Hervé Drolon

      Hervé Drolon - 2003-06-24

      This code was a copy/paste from my applications. It was tested in MFC, ATL and WTL (separatly of course) and it works fine for me (note that there's an error in your GetDIBits function).
      Yes I did correct an error when I responded to you, and the :: operator is used in C++ only.

      Hope it helps ?

      Herv

       
    • Hervé Drolon

      Hervé Drolon - 2003-06-24

      Nick Lilavois wrote :
      "One more thing- I was kind of hoping that by passing FIF_UNKNOWN to FreeImage_Save, that the function would check the extension of the filename to find out the format to use.

      Can I recomend that for the next version? "

      > It's not needed, IMHO (see how the generic writer of the BatchLoad sample works)

       
    • Anonymous

      Anonymous - 2003-06-24

      FYI, at least with VS 2003, FreeImage_Allocate requires the color mask parameters.

      it errors:

      main.c(204) : error C2198: 'FreeImage_Allocate' : too few arguments for call through pointer-to-function

      on line:

      dib = FreeImage_Allocate(exportbmp.bmWidth, exportbmp.bmHeight, exportbmp.bmBitsPixel);

      which I changed to:

      dib = FreeImage_Allocate(exportbmp.bmWidth, exportbmp.bmHeight, exportbmp.bmBitsPixel,0xFF000000,0x00FF0000,0x0000FF00);

      to make it compile.

      I hope that my guess of 0xFF000000,0x00FF0000,0x0000FF00
      is correct for HBITMAP data.

      are what the default values are- but I am writing 24 bit bitmaps not 32. Should I still be passing the color masks as 32?

      And yes- the FreeImage_GetFIFFromFilename makes my file reading code much shorter, thanks, but still no joy on file saving.

      Here is what I have now, exactly like your FAQ except for changing the names of the variables:

      if(exporthbm)
      {
        GetObject(exporthbm, sizeof(BITMAP), (LPSTR) &exportbmp);
        dib = FreeImage_Allocate(exportbmp.bmWidth, exportbmp.bmHeight, exportbmp.bmBitsPixel,0xFF000000,0x00FF0000,0x0000FF00);
        hdc =GetDC(hwnd);
        result=GetDIBits(hdc, exporthbm, 0, FreeImage_GetHeight(dib),
        FreeImage_GetBits(dib), FreeImage_GetInfo(dib), DIB_RGB_COLORS);
        ReleaseDC(hwnd, hdc);
                   
        if(strstr(exportfilename,".jpg")!=NULL)
        {
          FreeImage_Save(FIF_JPEG, dib, exportfilename, JPEG_QUALITYSUPERB);
        }
        else
        {
          FreeImage_Save(FreeImage_GetFIFFromFilename(exportfilename), dib, exportfilename, 0);
        }
        FreeImage_Unload(dib);
      }

      and it writes the bitmap fine with my own functions, which only write BMP and TGA.

       
    • Hervé Drolon

      Hervé Drolon - 2003-06-24

      Well, I don't know what to respond to you ...
      The FI_DEFAULT parameter was introduced to preserve C compatibility (The C language doesn't support default values) and it should work (I never tested it personnaly). But it's not surprising that MSVC 2003 doesn't understand this: MS compilers have never been known as good/standard C/C++ compilers (compared to Borland for example). When I have to program in C under a MS compiler, what I did is to rename .C files to .CPP and it usually works well. I suspect the MS C compiler to use C++ directives ...
      About the mask, it's only needed when you use masks (there's no masks with 24-bit images, only with 16 and 32-bit images), so you could use a zero value since you just export a HBITMAP.
      However, you should use the FreeImage_FIFSupportsExportBPP function when saving, just to check (JPEG format can only save 8 & 24-bit images for example).
      Lastly, for the save function, I cannot see what doesn't work because it always worked for me and other people using functions like this ...

       
      • Anonymous

        Anonymous - 2003-06-24

        Could the saving issue be VS 2003 related as well?

        I just installed it, I could reinstall VS6- it's not like I am using any new .NET functionality.

        So for FreeImage_Allocate, I should set the last three parameters to 0? The bitmaps I am saving will always be 24bit, simple but slightly high-res graphics, at max 4000 pixels square, at min 1400 pixels square.

        Could the file size be an issue?

        I will try renaming my main file .cpp instead of .c, but I doubt that will help the file saving issue.

         
    • Anonymous

      Anonymous - 2003-06-29

      FYI- I installed VS6 on a diferent computer, recompiled, and it runs fine, reads and saves files.

      I don't know if the problem was the VS2003 or something else on that computer, but at least the problem is solved.

       
    • Anonymous

      Anonymous - 2003-07-08

      FYI- my program is all done, and up and available for sale:

      http://www.utopiadigitalmedia.com/

      I gave you a mention and a link on the description page on the site as well as in the About box of the app itself.

       
    • Hervé Drolon

      Hervé Drolon - 2003-07-21

      Thanks,

      Your program has been added to the "Who Uses FreeImage" page.

       
    • Anonymous

      Anonymous - 2003-09-07

      An update:

      I have sold a number of copies of clockworks, and some of the customers have had the same problem with saving graphics files that I had.

      I have my own code for saving BMP, so I added that back into the program, gave them updates, and told those people to just save in BMP format instead, which works fine for them.

      The customers with the problems were all using win98 except one who was on XP. THe XP user had his screen in 16bit mode- when he switched to 24 bit it worked fine for PNG and JPG. I do not know the screen bitdepths of the win98 users.

       
    • Hervé Drolon

      Hervé Drolon - 2003-09-08

      Sorry but I don't understand the problem ...

      What is the format that cannot be saved ?
      Do you have more info on the caracteristics of this format (bitdepth, ...) ?

       
    • Floris van den Berg

      That's odd. BMP must be the most well tested format in the whole lib. I fed the DLL tons of different bmps (even incorrectly formatted ones!) and it loads and saves just fine. In all bitdepths. With and without RLE.

      You mention that when people switch from 16bit mode to 24 bit mode saving works. That's even more odd, because FreeImage has no clue whatsoever about your screen bitdepth. My wild but educated guess is that some other code in your prog produces this error.

       
    • Anonymous

      Anonymous - 2003-09-09

      No- they could not save in any format using the DLL. It is the same problem I was talking about from the beginning of this thread. BMP, PNG and JPG format were the three I gave users as options, and they could not save as any of them- the header information of the files get written, but no bitmap data.

      Because the DLL was not working, and customers were using the program, I wrote a patch to my program that uses my own code when writing BMP.

      That way they could save in BMP just fine with my code, and the freeimage DLL was only used if they tried other formats.

       
    • Anonymous

      Anonymous - 2003-09-09

      And the error is definitely not in my code- as I said, it saves fine using my own BMP code, the code for using the DLL came from this site, and I posted my code right here in this thread.

       
    • Anonymous

      Anonymous - 2003-09-09

      ... and just one (the XP person) did the screen bit depth thing. All other users with 2000 and XP were using it fine- the four other people who could not save files were using 98 or ME.

      I do not know if I had any successful users with 98 or ME, but I tested it on a clean 98 system and it worked fine with your dll.

       

Log in to post a comment.