Recent

Author Topic: Inserting, Saving and Loading Images  (Read 27070 times)

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #30 on: September 19, 2016, 07:25:54 pm »
Please note that stretch drawing might not always be the desired result.
So, it's up to you how to draw the inserted inline object, you'll always have the size of the rectangle area where the object needs to be drawn at. (No pixels would be drawn outside of the area)

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #31 on: September 19, 2016, 08:30:40 pm »
Thanks, but I am not sure why I would not want to resize something. That said, I am going to build a function to resize proportionately, which is what I always need.

Rick.
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #32 on: September 19, 2016, 09:41:54 pm »
Unfortunately it isn't over, an inserted image won't save to disk.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #33 on: September 19, 2016, 09:44:05 pm »
Unfortunately it isn't over, an inserted image won't save to disk.
Yeah, I know. You mentioned it several times before :)
Working on it.

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #34 on: September 19, 2016, 10:00:52 pm »
Sorry for the nag... I had only thought that once it had a grip frame it meant that it was built by a callback, and could be saved.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #35 on: September 19, 2016, 10:26:00 pm »
Sorry for the nag... I had only thought that once it had a grip frame it meant that it was built by a callback, and could be saved.
Not that easy. Windows needs to recognize the image ... as an image... in order to be able to save it to rtf.
« Last Edit: September 19, 2016, 10:30:26 pm by skalogryz »

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #36 on: September 20, 2016, 01:47:31 pm »
I came across this code that is supposed to work for RxRichEdit. I has function calls that are specific to that driver, so it hard for me to sort out what is actually needed. I also think that it defective code... incomplete call formats that omit parameters. But maybe you might can get something out of it.

Code: Pascal  [Select][+][-]
  1. // Insert a image into a TRxRichEdit?
  2. // Author: Thomas Stutz
  3.  
  4.  
  5. uses
  6.   RichEdit;
  7.  
  8. // Stream Callback function
  9. type
  10.   TEditStreamCallBack = function(dwCookie: Longint; pbBuff: PByte;
  11.     cb: Longint; var pcb: Longint): DWORD;
  12.   stdcall;
  13.  
  14.   TEditStream = record
  15.     dwCookie: Longint;
  16.     dwError: Longint;
  17.     pfnCallback: TEditStreamCallBack;
  18.   end;
  19.  
  20. // RichEdit Type
  21. type
  22.   TMyRichEdit = TRxRichEdit;
  23.  
  24. // EditStreamInCallback callback function
  25. function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
  26.   cb: Longint; var pcb: Longint): DWORD; stdcall;
  27.   // by P. Below
  28. var
  29.   theStream: TStream;
  30.   dataAvail: LongInt;
  31. begin
  32.   theStream := TStream(dwCookie);
  33.   with theStream do
  34.   begin
  35.     dataAvail := Size - Position;
  36.     Result := 0;
  37.     if dataAvail <= cb then
  38.     begin
  39.       pcb := read(pbBuff^, dataAvail);
  40.       if pcb <> dataAvail then
  41.         Result := UINT(E_FAIL);
  42.     end
  43.     else
  44.     begin
  45.       pcb := read(pbBuff^, cb);
  46.       if pcb <> cb then
  47.         Result := UINT(E_FAIL);
  48.     end;
  49.   end;
  50. end;
  51.  
  52. // Insert Stream into RichEdit
  53. procedure PutRTFSelection(RichEdit: TMyRichEdit; SourceStream: TStream);
  54.   // by P. Below
  55. var
  56.   EditStream: TEditStream;
  57. begin
  58.   with EditStream do
  59.   begin
  60.     dwCookie := Longint(SourceStream);
  61.     dwError := 0;
  62.     pfnCallback := EditStreamInCallBack;  // ***missing parameter calls***
  63.   end;
  64.   RichEdit.Perform(EM_STREAMIN, SF_RTF or SFF_SELECTION, Longint(@EditStream));
  65. end;
  66.  
  67. // Convert Bitmap to RTF Code
  68. function BitmapToRTF(pict: TBitmap): string;
  69. // by D3k
  70. var
  71.   bi, bb, rtf: string;
  72.   bis, bbs: Cardinal;
  73.   achar: ShortString;
  74.   hexpict: string;
  75.   I: Integer;
  76. begin
  77.   GetDIBSizes(pict.Handle, bis, bbs);    // unique to RxRichEdit
  78.   SetLength(bi, bis);
  79.   SetLength(bb, bbs);
  80.   GetDIB(pict.Handle, pict.Palette, PChar(bi)^, PChar(bb)^);  // unique to RxRichEdit
  81.   rtf := '{\rtf1 {\pict\dibitmap ';
  82.   SetLength(hexpict, (Length(bb) + Length(bi)) * 2);
  83.   I := 2;
  84.   for bis := 1 to Length(bi) do
  85.   begin
  86.     achar := Format('%x', [Integer(bi[bis])]);
  87.     if Length(achar) = 1 then
  88.       achar := '0' + achar;
  89.     hexpict[I - 1] := achar[1];
  90.     hexpict[I] := achar[2];
  91.     Inc(I, 2);
  92.   end;
  93.   for bbs := 1 to Length(bb) do
  94.   begin
  95.     achar := Format('%x', [Integer(bb[bbs])]);
  96.     if Length(achar) = 1 then
  97.       achar := '0' + achar;
  98.     hexpict[I - 1] := achar[1];
  99.     hexpict[I] := achar[2];
  100.     Inc(I, 2);
  101.   end;
  102.   rtf := rtf + hexpict + ' }}';
  103.   Result := rtf;
  104. end;
  105.  
  106.  
  107. // Example to insert image from Image1 into RxRichEdit1
  108. procedure TForm1.Button1Click(Sender: TObject);
  109. var
  110.   SS: TStringStream;
  111.   BMP: TBitmap;
  112. begin
  113.   BMP := TBitmap.Create;
  114.   BMP := Image1.Picture.Bitmap;
  115.   SS  := TStringStream.Create(BitmapToRTF(BMP));
  116.   try
  117.     PutRTFSelection(RxRichEdit1, SS);
  118.   finally
  119.     SS.Free;
  120.   end;
  121. end;
  122.  

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Inserting, Saving and Loading Images
« Reply #37 on: September 20, 2016, 02:05:50 pm »
I came across this code that is supposed to work for RxRichEdit. ... I also think that it defective code... .

Code: Pascal  [Select][+][-]
  1.     pfnCallback := EditStreamInCallBack;  // ***missing parameter calls***
  2.  
should read (for FPC)
Code: Pascal  [Select][+][-]
  1.     pfnCallback := @EditStreamInCallBack;  // ***missing parameter calls***
  2.  

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #38 on: September 20, 2016, 02:28:23 pm »
I came across this code that is supposed to work for RxRichEdit.
Well... instead of doing direct RTF injections, you could try to use these functions in richmemoutils.pas
  InsertImageFromFile
or
  InsertImageFromFileNoResize


rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #39 on: September 20, 2016, 07:26:18 pm »
Looking at the code that I recently posted, I noticed that the function BitmapToRTF is building place holder for the image within the RTF file code.

InDelInline is not building that code. What it inserts is {\pict\wmetafile0}, which means there was noting to insert. Normally it would be something like the following...

{\pict\wmetafile8\picwgoal5550\pichgoal4560
0100090000033afc0100000024fc01000000050000000b0200000000050000000c025a1a222324
fc0100430f2000cc000000ff005401000000005a1a2223000000002800000054010000ff000000

It starts with wmetafile8 instead of wmetafile0, and the numbers and alphabet are what the function BitmapToRTF builds.

When I copied and pasted the full body of the wmetafile8 to replace the wmetafile0 series, it loaded, was resizable, and could be saved.

It seems that all you need is to improvise a similar function to BitmapToRTF.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #40 on: September 20, 2016, 07:50:44 pm »
It seems that all you need is to improvise a similar function to BitmapToRTF.
That's another hack, that I'd like to avoid. However, you're free to use it.

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #41 on: September 20, 2016, 08:24:57 pm »
OK. Everything that I have researched states that RichEdit was never built to do images. To have them you have to "hack" or do a "workaound." If it is done properly it works. Not because of RichEdit, but on account of modern RTF methods.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Inserting, Saving and Loading Images
« Reply #42 on: September 20, 2016, 08:42:21 pm »
OK. Everything that I have researched states that RichEdit was never built to do images.
Not exactly so.
Windows RichEdit is designed to embed OLE objects.
OLE used to be ...and infact is ... Windows backbone technology, and microsoft used it heavily back in the days (switching to .NET in 2000s).
Thus, RichEdit was designed with OLE objects in mind, even for simple stuff like links of images.

In the most recent versions of RichEdit (i think starting Windows 10), there's a special non OLE API to embed an image. (Which is not applicable for earlier versions of Windows), so the only cross-Windows solution is to use OLE.
Which is done by Inline objects... however, since the documentation on RichEdit internals is quite poor, lots of the development is a guess work.

To have them you have to "hack" or do a "workaound."
That's a common practice that has been in use since Delphi RichEdit days.
Yet again, I'm not going to use it with the official RichMemo inline objects, but anyone else are free to use it, since it works perfectly fine for all the small needs.
Please note that you don't have to use inline objects at all at this point.

tk

  • Sr. Member
  • ****
  • Posts: 361
Re: Inserting, Saving and Loading Images
« Reply #43 on: September 20, 2016, 09:09:08 pm »
OK. Everything that I have researched states that RichEdit was never built to do images.

That I would not say, but you might try KMemo http://tkweb.eu/en/delphicomp/kmemo.html, it should be able to handle them fine already (I mean the newest repo download).

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: Inserting, Saving and Loading Images
« Reply #44 on: September 20, 2016, 09:53:35 pm »
Very well, and it is only an argument, but there is a difference between "capacity" and "functionality". Windows built RichEdit with capacity, but not for functionality. The actual production of functionality was being reserved for them. That is how you make money.

To be "cross-platform" with RichMemo you have to develop the functionality. Moreover, it needs to not be dependent on the limitations of RichEdit. It needs to be RTF driven.

Inserting the RTF code for an image is simply complying with RTF rules.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

 

TinyPortal © 2005-2018