Tk library function.
A tk photo is returned using the following structure:
typedef struct { unsigned char *pixelPtr; /* the pixel data */ int width; /* image width in pixels */ int height; /* image height in pixels */ int pitch; /* byte offset between image rows in memory */ int pixelSize; /* byte count for each pixel */ int offset[4]; /* array of offsets to get to the red, green, blue and transparent value */ } Tk_PhotoImageBlock;
HaO 2018-11-29 (See CLT thread "Tk_PhotoGetImage: whivh block parameter are constant" started 2018-11-28 8:05)
The returned format is currently always:
HaO 2018-11-29: The following example is derived from the code of "wm icon" in tk8.6.9 win/tkWinWm.c, proc WmIconphotoCmd.
// Paint a photo image to the printer DC // @param interp tcl interpreter // @param hDC is a printer device context // @param oImageName tcl object with tk imsge name // @param DestPosX Destination X position // @param DestPosY Destination Y position // @param DestWidth Width of destination image, or 0 to use original size // @param DestHeight Height of destination image or 0 to use original size static int PaintPhoto( Tcl_Interp *interp, HDC hDC, Tcl_Obj *CONST oImageName, int DestPosX, int DestPosY, int DestWidth, int DestHeight) { Tk_PhotoImageBlock sImageBlock; Tk_PhotoHandle hPhoto; HBITMAP hDIB; int IndexCur; // Access bgraPixel as void ptr or unsigned char ptr union {unsigned char *ptr; void *voidPtr;} bgraPixel; BITMAPINFO bmInfo; // The creation of the DIP is from // tk8.6.9 win/tkWinWm.c, proc WmIconphotoCmd if ( NULL == (hPhoto = Tk_FindPhoto(interp, Tcl_GetString(oImageName)))) { Tcl_SetStringObj( Tcl_GetObjResult(interp), "No photo",-1); return TCL_ERROR; } Tk_PhotoGetImage(hPhoto, &sImageBlock); // pixelSize = 4 // pitch = width * 4 // offset = 0:0,1:1,2:2,3:3 // Create device-independant color bitmap. ZeroMemory(&bmInfo, sizeof bmInfo); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = sImageBlock.width; bmInfo.bmiHeader.biHeight = -sImageBlock.height; bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = 32; bmInfo.bmiHeader.biCompression = BI_RGB; // the first parameter is the dc, which may be 0. // no difference to specify it hDIB = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS, &bgraPixel.voidPtr, NULL, 0); if (!hDIB) { Tcl_SetStringObj( Tcl_GetObjResult(interp), "No memory",-1); return TCL_ERROR; } // Convert the photo image data into BGRA format (RGBQUAD). for (IndexCur = 0 ; IndexCur < sImageBlock.height * sImageBlock.width * 4 ; IndexCur += 4) { bgraPixel.ptr[IndexCur] = sImageBlock.pixelPtr[IndexCur+2]; bgraPixel.ptr[IndexCur+1] = sImageBlock.pixelPtr[IndexCur+1]; bgraPixel.ptr[IndexCur+2] = sImageBlock.pixelPtr[IndexCur+0]; bgraPixel.ptr[IndexCur+3] = sImageBlock.pixelPtr[IndexCur+3]; } // Use original width and height if not given if (DestWidth == 0) { DestWidth = sImageBlock.width; } if (DestHeight == 0) { DestHeight = sImageBlock.height; } // Use StretchDIBits with full image. // The printer driver may use additional color info to do better // interpolation if (GDI_ERROR == StretchDIBits( pdlg.hDC, // handle to DC DestPosX, // x-coord of destination upper-left corner DestPosY, // y-coord of destination upper-left corner DestWidth, // width of destination rectangle DestHeight, // height of destination rectangle 0, // x-coord of source upper-left corner 0, // y-coord of source upper-left corner sImageBlock.width, // width of source rectangle sImageBlock.height, // height of source rectangle bgraPixel.voidPtr, // bitmap bits &bmInfo, // bitmap data DIB_RGB_COLORS, // usage options SRCCOPY // raster operation code ) ) { DeleteObject(hDIB); // As this is invoked within the driver, return a driver error Tcl_SetStringObj( Tcl_GetObjResult(interp), "Printer driver error",-1); return TCL_ERROR; } DeleteObject(hDIB); return TCL_OK; }