Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

thread182-111552

Status
Not open for further replies.

WDStryKer

Programmer
Sep 13, 2016
3
PH
hi scott. your solution was great! i have been encountering the same problem when i try to print item catalogues with photos. apparently the real culprit here was the size of the photos loaded (don't go beyond 200 x 200 pix) with over 30,000 items in my database my problem was how to determine which items had huge photos. i used part of your code to do this and it worked great!

thanks
 
You see the thread shortcut is only expanded in the post text, not in the thread title, so it would be nice you mend this, you can edit your post, also your thread title, at least for a day. If that timeout has already past for you, when you come back, you can redflag your thread and ask for assitance of fixing this (red flagging is not only for the narrow purpose of - well- red flagging threads or posts with any inappropriate content, it's mainly getting attention and assistance of administration of tek-tips).

Let me just put your reference here, so it gets obvious what you wanted to refer to: thread182-111552

Besides that, while expressing your gratitude, it would be interesting how that error handling helped and what "part of your code" you used to find too large photos. I can imagine those throwing errors because of being too big are the ones you addressed.

And let me end on this really just once more pointing out storing photos - or anything - in general fields is a bad idea. General fields is still based on very old OLE concepts, which are outdated and not supported by most of today OLE servers aside of those Microsoft developed. Today you should rather use blob fields, but of course that's not part of legacy foxpro. Not sure, though, if you're using a legacy foxpro version or just found a solution in the legacy foxpro forum and used it in VFP9, which seems more likely to me.

Besides blobs, I would rather suggest leaving files for themselves, the good part of a file based database is, that it lives in a directory anyway, and this directory is a good place for any related files like pictures. And just like the DBF contains an offset into the tables FPT file for any memo, gen, or blob field content, you can use a char field to store a file reference in the form of a file path or just the file name, when you put the files in a specific folder, eg the data folder or a subfolder. You can even have the reverse reference by renaming picture file copies with the numeric or alphanumeric ID of the DBF record it belongs to, which needs no new DBF field, just uses the matching by ID typical for any relation of two tables via normal primary/foreign key matching.

And aside of that, once you have your pictures in their natural single file format, you can work on them with FoxPros gdiplus classes or VFPXs gdiplusx projects code, it's quite easy to determine picture sizes and also to resize too large pictures in batch processing.

Here's a routine using gdiplusx (usable in VFP9). Prerequisite is having gdiplusx system.app and having done [tt]DO system.app[/tt] as initialization to let that add _Screen.System and _Screen.System.Drawing objects, etc for your gdi usage:

Code:
CD into the base folder of gdiplusx system.app
Do Locfile("system.app")
PictureShrink(AddBS(Home())+"Samples\Tastrade\Bitmaps\buchstev.bmp",200)

#Define PixelFormatGDI 0x00020000 && Is a GDI-supported format
#Define PixelFormat24bppRGB (8 + (0x1800)+PixelFormatGDI)
#Define UnitPixel  2

Procedure PictureShrink(tcPictureFilename, tnMaxDimension) && tnMaxDimension for limiting both picture dimensions
   Local loImg, lnOldWidth, lnOldHeight, lnNewWidth, lnNewHeight, loBmp, loGraphics
   loImg = _Screen.System.Drawing.Bitmap.FromFile(tcPictureFilename,.T.)

   * These two lines are sufficient to determine picture dimensions:
   lnOldWidth  = loImg.Size.Width
   lnOldHeight = loImg.Size.Height

   If lnOldWidth  > lnOldHeight
      lnNewWidth  = tnMaxDimension
      * Keeping the aspect ratio:
      lnNewHeight = Round(tnMaxDimension*lnOldHeight/lnOldWidth,0)
   Else
      lnNewHeight = tnMaxDimension
      * Keeping the aspect ratio:
      lnNewWidth  = Round(tnMaxDimension*lnOldWidth/lnOldHeight,0)
   Endif

   If lnNewHeight<=lnOldHeight Or lnNewWidth<=lnOldWidth && is the picture shrinked?
      loBmp = _Screen.System.Drawing.Bitmap.New(lnNewWidth,lnNewHeight,0,PixelFormat24bppRGB)
      loBmp.SetResolution(loImg.HorizontalResolution,loImg.VerticalResolution)
      loGraphics = _Screen.System.Drawing.Graphics.FromImage(loBmp)
      loGraphics.DrawImage(loImg,0,0,loBmp.Size.Width,loBmp.Size.Height,0,0,loImg.Size.Width,loImg.Size.Height,UnitPixel)

      loBmp.Save(Forceext(tcPictureFilename,"shrinked.jpg"))

      loGraphics.Dispose()
      loBmp.Dispose()
   Endif

   loImg.Dispose()
Endproc

You can do more, eg use a specific encoder and encoder quality for the new target file you create to enhance the picture or at least keep the quality. PNG is a nice format with the possibility to create a new picture file with lossless compression. Just note the original picture I use here comes with VFP9 and is a low quality BMP file, thus resulting in a lower dimension, yet larger byte sizes JPG file, this is not the normal case, though.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top