Dear Shuming,
Pictures inside an Excel sheet are not accessible via oSheet:Cells(nI,i):picture โ that property doesn't exist in Excel's OLE object model. Images live in the sheet's Shapes collection, not on cells. To grab one and save it as a bmp/jpg, the reliable route through FWH is: use OLE to copy the shape to the clipboard, then let FWH read the clipboard bitmap and write it to disk.
Key building blocks in FWH
- FW_SaveImage( uImage, cFile, nJpegQuality ) โ when the first argument is empty/nil, it reads the bitmap directly from the clipboard and saves it to cFile, deducing the format (bmp/jpg/png/gif/tif) from the file extension. 0-cite-0
- TClipBoard():New( 2 ):GetBitmap() โ returns an HBITMAP handle from the clipboard, which you can also feed to FW_SaveImage(). 0-cite-1
- oImage:SaveImage( cFile, nFmt, nQuality ) on a TImage โ saves the currently held bitmap (0=BMP, 1/2=JPG, 13=PNG). 0-cite-2
Approach
Iterate oSheet:Shapes, and for each shape use its TopLeftCell to know which cell (nI, i) it sits on. Then call the shape's CopyPicture method (Excel COM: CopyPicture( xlScreen := 1, xlBitmap := 2 )) to put it on the clipboard, and save it with FW_SaveImage:
// oSheet is your ActiveSheet
local oShapes := oSheet:Shapes
local oShape, nRow, nCol, cFile, n
for n := 1 to oShapes:Count
oShape := oShapes:Item( n )
nRow := oShape:TopLeftCell:Row // row where the picture starts
nCol := oShape:TopLeftCell:Column // column where it starts
// copy this shape to the Windows clipboard as a bitmap
oShape:CopyPicture( 1, 2 ) // xlScreen, xlBitmap
cFile := "cell_" + LTrim(Str(nRow)) + "_" + LTrim(Str(nCol)) + ".jpg"
// first arg empty -> FW_SaveImage reads the bitmap from the clipboard
FW_SaveImage( nil, cFile, 90 ) // 90 = JPEG quality; use .bmp ext for bitmap
next
Notes:
- Use a .bmp extension in cFile to save as bitmap, or .jpg/.png for other formats โ FW_SaveImage() picks the encoder from the extension. 0-cite-3
- If you prefer working with a handle explicitly, do local hBmp := TClipBoard():New(2):GetBitmap() after CopyPicture, then FW_SaveImage( hBmp, cFile, 90 ). 0-cite-1
- If a cell can contain multiple pictures or you need only the one anchored to a specific (nI,i), filter with if nRow == nI .and. nCol == i.
One caveat: CopyPicture is an Excel COM (TOleAuto) call, so it only works with the OLE-automation path you're already using (ExcelObj() / oExcel:ActiveSheet()), not with the native TWorkSheet/TXlsxReader readers, which do not expose embedded shapes. 0-cite-4
If you want me to turn this into a complete, tested sample program in the repo, let me know and I can lay out a plan for it.