Allow image objects to store image content inside the report file instead of requiring an external image path, while preserving existing dynamic DataField image behavior and existing report compatibility.
TReportImageObjectalready owns aTPictureinstance through itsPictureproperty.- The serializer already writes non-empty static image content as Base64
PictureDatawithPictureClass. - The serializer already restores
PictureDatawhen a report file is opened. - A static embedded image can render when
DataFieldis empty andPictureis assigned. - Designer controls do not currently provide a clear workflow to load, replace, or clear embedded image data.
- Direct vector PDF export currently emits image commands only when an external file-backed source is available.
- Preserve existing
PictureDataandPictureClassreport-file fields. - Do not introduce a new file format for the first implementation.
- Keep
DataFieldimage binding behavior unchanged unless a separate fallback design is approved. - If
DataFieldis empty, an embeddedPictureis the static image source. - If
DataFieldis set, dynamic row image resolution remains authoritative in the initial implementation. - Existing image-path reports must continue to load and render unchanged.
- Existing reports without image data must continue to load unchanged.
- Implement incrementally and commit only at safe milestones.
- Do not redesign the image object or serializer without evidence that existing fields are insufficient.
- Do not combine embedded-image work with SVG/EMF vector-preservation work.
- Do not silently change how blank or invalid dataset image paths behave.
- Use owned streams and graphics with
try/finally. - Avoid holding temporary image objects or file handles after import/export.
Existing runtime units:
source/Vittix.Report.Objects.passource/Vittix.Report.Serializer.passource/Vittix.Report.Engine.passource/Vittix.Report.Export.Commands.passource/Vittix.Report.Export.VectorPDF.pas
Existing designer units:
vittixdesigner/Frm.Main.pasvittixdesigner/Frm.Main.PropertyPanelHelpers.pasvittixdesigner/Frm.Main.PropertyEditorHelpers.pas
Possible new designer unit:
vittixdesigner/Frm.ImageEditor.pas
Status: Completed
Goal:
Confirm what is already supported before modifying code.
Findings:
- Report serialization already supports embedded static image bytes.
PictureDatacontains Base64-encoded image content.PictureClassidentifies the graphic type required when loading.- Runtime image drawing already supports a static assigned
PicturewhenDataFieldis empty. - Designer assignment and vector PDF handling are the missing user-visible parts.
Validation:
- Review serializer save/load behavior.
- Review image object drawing behavior.
- Review vector PDF image command source requirements.
- No code behavior changes.
Safe commit condition:
- This development document only.
Suggested commit:
docs(image): add embedded image development plan
Status: Completed and manually validated
Goal:
Allow a selected image object to load an image into its embedded Picture content.
Implementation:
- Add a designer action for an image object such as
Load Embedded Image.... - Load the selected graphic into
TReportImageObject.Picture. - Support formats currently loadable by the runtime image loader first.
- Preserve existing image layout properties:
Stretch,Center,Proportional, and border settings. - Do not automatically change
DataFieldwithout an explicit user decision. - Mark the report modified after a successful import.
- Refresh the design surface and property display after assignment.
Implemented:
- Add a synthetic
Pictureaction row in the property inspector for image objects. - Open an embedded image editor from the
Pictureellipsis editor or by double-clicking an image on the design surface. - Support file import and clipboard bitmap paste inside the editor.
- Store imported image content through the existing owned
TPicture. - Record import as an undoable designer command.
- Leave
DataFieldunchanged.
Initial supported formats:
- BMP
- JPEG
- PNG
- GIF
- WMF
- EMF
Deferred:
- SVG import, unless the existing graphic stack supplies safe load/save serialization without extra runtime dependencies.
Risks:
- Imported graphic classes must be registered and reloadable through existing serialization.
- Large image files can substantially increase report-file size.
- Assigning an embedded image while
DataFieldremains set can appear to have no effect at runtime because dynamic binding remains authoritative.
Validation:
- Import each initially supported format.
- Image appears in designer immediately.
- Save and reopen the report; image remains present.
- Preview and print display the embedded image when
DataFieldis empty. - Existing dynamic image reports remain unchanged.
Safe commit condition:
- Designer import works for static image objects.
- Runtime and designer packages compile.
- No vector PDF behavior change is required for this milestone.
Status: Pending
Goal:
Make embedded image ownership and replacement explicit in the designer.
Implementation:
- Add
Clear Embedded Imagefor selected image objects. - Allow
Load Embedded Image...to replace a prior embedded image. - Display a useful property/status indication such as
EmbeddedorNone. - If both
DataFieldand an embedded image exist, show that the dataset field is used at runtime.
Risks:
- Clearing only the embedded image must not clear
DataFieldor layout properties. - The designer must not leak the replaced
TGraphic.
Validation:
- Replacing an image updates preview after save/reopen.
- Clearing an embedded image removes
PictureDataon the next save. - Clearing does not mutate
DataField. - Canceling file selection makes no change.
Safe commit condition:
- Load, replace, and clear actions are reversible and validated.
Status: Pending
Goal:
Provide a stable report artifact for embedded-image behavior.
Implementation:
- Add or update a regression report containing an image object with:
DataField = ''- Embedded
PictureData - Known scaling and centering settings
- Keep the sample small enough for source control and quick testing.
Validation:
- Report opens in the designer.
- Image appears on design surface.
- Preview displays image.
- Print path displays image.
- Save/reopen does not corrupt image content.
Safe commit condition:
- Regression artifact and behavior verified manually.
Status: Pending
Goal:
Render embedded raster images in direct vector PDF output without requiring a temporary external path.
Implementation direction:
- Extend
TReportExportImageCommandto carry owned embedded image content or encoded source bytes in addition toSource. - When
DataFieldis empty andPicturecontains a supported embedded graphic, emit an image export command using embedded data. - Extend
Vittix.Report.Export.VectorPDF.pasto write embedded PNG/JPEG content using the same sizing and placement behavior as file-backed images. - Retain file-backed
Sourcesupport without behavior change. - Ensure command lifetime owns any copied stream or byte array needed after report rendering.
Initial support:
- Embedded PNG
- Embedded JPEG
Deferred:
- Embedded bitmap conversion policy.
- EMF/WMF preservation as vector PDF content.
- SVG vector import and PDF preservation.
Risks:
- Image byte ownership must not reference a report graphic after its owner is freed.
- PNG alpha/transparency handling must remain correct.
- Memory usage increases if many large embedded images are copied into export commands.
- Export output must match preview placement and scaling.
Validation:
- Embedded PNG renders in direct vector PDF.
- Embedded JPEG renders in direct vector PDF.
- Existing path-based PNG/JPEG PDF export remains unchanged.
- Multi-page reports do not duplicate, lose, or leak image data.
- Repeated exports remain stable.
Safe commit condition:
- Runtime package and runner compile.
- Embedded PNG/JPEG PDF regression passes.
- Existing vector PDF regressions pass.
Status: Deferred
Goal:
Decide whether an embedded image should act as a placeholder when a DataField path is blank, missing, or invalid.
Reason For Deferral:
- Current dynamic behavior clears the previous row image when a dataset field has no valid image.
- Automatically using embedded image fallback would change report output for existing dynamic reports.
- This requires an explicit property or documented opt-in behavior rather than an implicit change.
Possible future property:
UseEmbeddedImageAsFallback: Boolean
Compatibility requirement:
- Default must preserve current dynamic image behavior.
Status: Deferred
Goal:
Consider additional embedded image types only after basic embedded image workflow and PDF export are stable.
Candidates:
- BMP converted to PNG for PDF export
- WMF/EMF displayed and printed through existing VCL graphics
- WMF/EMF vector-preserving PDF export
- SVG import and rendering
Reason For Deferral:
- These formats introduce format-specific loaders, conversion behavior, and PDF rendering decisions.
- They should not increase the risk of the initial embedded PNG/JPEG workflow.
- Import a BMP, JPEG, and PNG embedded image in the designer.
- Save report and reopen it.
- Confirm static embedded image displays when
DataFieldis empty. - Confirm
DataFieldimage reports remain dynamic and unchanged. - Confirm replacing and clearing an embedded image works without leaking resources.
- Preview static image report.
- Print static image report.
- Export static image report through existing PDF path.
- Export embedded PNG/JPEG through direct vector PDF after M5.
- Test empty report and report without images.
- Test repeated open/save and repeated preview/export cycles.
- Check report-file size impact with large source images.
- Check for obvious memory and GDI handle growth.
- Commit M1 as documentation only.
- Commit M2 and M3 independently unless their UI implementation is inseparable.
- Commit regression artifacts separately when practical.
- Commit vector PDF support only after static designer/runtime embedding is validated.
- Do not mix SVG/EMF work into embedded raster image commits.