Re: [Iup-users] cdCanvasCreateImage always returns NULL
There are many ways to implement a buffered image. I couldn't tell what's the best way or why your code is not working. I don't know what type of canvas is _CANVAS_PTR cd, for instance. We can start by why "part of a drawn canvas"? Because by this code: if (note->render != NULL) { cdCanvasPutImageRect(cd, note->render, x, y, 0, 0, 0, 0); return; } It seems that if render exists all your canvas will be used. If you explain to me the logic of what you are trying to achieve, maybe we can find a solution, because CD already interesting support for double buffer drawing. Best, Scuri Em seg., 30 de ago. de 2021 às 22:51, Isaac Raway escreveu: > I am trying to capture part of a drawn canvas to an image so I can save > some expensive drawing operations. > > I try to do this with: > > void draw_note(_CANVAS_PTR cd, int viewMode, int active, tNOTE *note, int > x, int y, int offsetX, int offsetY, tWIN *win, RECT clip_wh) > { > if (note->render != NULL) { > cdCanvasPutImageRect(cd, note->render, x, y, 0, 0, 0, 0); > return; > } > > // --- drawing code removed --- > > note->render = cdCanvasCreateImage(cd, note->graphW, note->graphH); > cdCanvasGetImage(cd, note->render, note->graphW, note->graphH); > } > > The problem is that cdCanvasCreateImage always returns NULL, so the > drawing results are not cached. > > My canvas is mapped like so: > > int graph_mapcb(Ihandle* self) > { > tWIN *win = (tWIN *)IupGetAttribute(self, "WIND"); > > cdInitGdiPlus(); > cdUseContextPlus(1); > if (self == win->notes_graph) { > win->notes_cdReal = cdCreateCanvas(CD_NATIVEWINDOW, > win->notes_graph); > win->notes_cdGraph = win->notes_cdReal;// > cdCreateCanvas(CD_DBUFFER, win->notes_cdReal); // was originally this > } else if (self == win->daily_graph) { > win->daily_cdReal = cdCreateCanvas(CD_NATIVEWINDOW, > win->daily_graph); > win->daily_cdGraph = win->daily_cdReal;// > cdCreateCanvas(CD_DBUFFER, win->daily_cdReal); // was originally this > } > return (IUP_DEFAULT); > } > > Any ideas why this isn't working? > ___ > Iup-users mailing list > Iup-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/iup-users > ___ Iup-users mailing list Iup-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iup-users
Re: [Iup-users] cdCanvasCreateImage always returns NULL
On 8/31/21 11:05 AM, Isaac Raway wrote: > I am trying to capture part of a drawn canvas to an image so I can save some > expensive drawing operations. > [...] G'day Isaac, This is a little left-field, and the resource trade-off may not be what you want, but here's a suggestion anyway... You can draw an image in a canvas, and then save it in some appropriate format. If the output format is PDF, then GhostScript can render it to a Netpbm format (assuming netpbm was included at build time, which is likely). Netpbm provides portable pixel formats (PBM, PGM and PPM). PBM is black/white; PGM is greyscale; PPM is colour. GhostScript on my system shows the following output devices in the Netpbm family: pbm pbmraw pgm pgmraw pgnm pgnmraw png16 png16m png256 png48 pngalpha pnggray pngmono pngmonod pnm pnmraw ppm ppmraw The manual page for "netpbm" notes that there are over 220 separate commands in the netpbm suite. In particular, the program "pamcut" lets you cut a rectangle out of an image, and produce another Netpbm image. So, from this point there are at least two ways to proceed: 0: (Draw the expensive things in their own canvas.) -- 1. Use external programs: 1.1 Save the canvas as a temporary PDF; 1.2 Discard/delete/destroy the temporary canvas; 1.3 Use GhostScript command (gs) to render the PDF to a suitable Netpbm format; 1.4 If required, use pamcut to extract the portions of the image that you want to keep, into a second Netpbm temporary file; 1.5 Import the desired image as an IM image, and then render it into your main application interface; and 1.6 Clean up temporary files. -- * The second way is identical to the first, except that you link the netpbm library into your application: 2.1 The initial separate-canvas-and-save-as-a-CD-supported-format file will perhaps remain; 2.2 As before, if the output is PDF or PostScript, then GhostScript may need to be run externally; 2.2 Once the rendered image is read in via IM, The remaining steps (e.g. pamcut) could be done in memory; 2.3 Of course, clean up temporary files as you go; 2.4 ?? I haven't checked, but perhaps some of the image operations (especially cropping the image) could be done by IM, before pasting the desired result into a suitable area in the GUI. -- As a final note, I've found that "qpdf" is a handy tool for decompressing PDFs back into a text format, so you can see the drawing primitives in plain text (as PostScript commands). This may be a useful intermediate debugging step. -- Hope this helps, s-b etc etc etc ___ Iup-users mailing list Iup-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iup-users
[Iup-users] cdCanvasCreateImage always returns NULL
I am trying to capture part of a drawn canvas to an image so I can save some expensive drawing operations. I try to do this with: void draw_note(_CANVAS_PTR cd, int viewMode, int active, tNOTE *note, int x, int y, int offsetX, int offsetY, tWIN *win, RECT clip_wh) { if (note->render != NULL) { cdCanvasPutImageRect(cd, note->render, x, y, 0, 0, 0, 0); return; } // --- drawing code removed --- note->render = cdCanvasCreateImage(cd, note->graphW, note->graphH); cdCanvasGetImage(cd, note->render, note->graphW, note->graphH); } The problem is that cdCanvasCreateImage always returns NULL, so the drawing results are not cached. My canvas is mapped like so: int graph_mapcb(Ihandle* self) { tWIN *win = (tWIN *)IupGetAttribute(self, "WIND"); cdInitGdiPlus(); cdUseContextPlus(1); if (self == win->notes_graph) { win->notes_cdReal = cdCreateCanvas(CD_NATIVEWINDOW, win->notes_graph); win->notes_cdGraph = win->notes_cdReal;// cdCreateCanvas(CD_DBUFFER, win->notes_cdReal); // was originally this } else if (self == win->daily_graph) { win->daily_cdReal = cdCreateCanvas(CD_NATIVEWINDOW, win->daily_graph); win->daily_cdGraph = win->daily_cdReal;// cdCreateCanvas(CD_DBUFFER, win->daily_cdReal); // was originally this } return (IUP_DEFAULT); } Any ideas why this isn't working?___ Iup-users mailing list Iup-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iup-users