ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Copy image from .PNG file to clipboard in DPR?
 New Topic  Reply to Topic
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

PeterPanino

933 Posts

Posted - Mar 22 2014 :  08:52:36  Show Profile  Reply
Hi! In a CONSOLE program, I want to load a .PNG file and copy the image to the clipboard. Is this possible?

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  09:04:04  Show Profile  Reply
Sure. Create a TIEBitmap and use TImageEnIO created at runtime attached to the TIEBitmap to load the image, then use TImageEnProc created at runtime attached to the TIEBitmap and then copy it to the clipboard with TImageEnProc.CopyToClipboard. Then free the TIEBitmap, TImageEnIo and TImageEnProc.

William Miller
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  09:47:52  Show Profile  Reply
Hi William, thanks.

The help file states that for TIEBitmap I need hyieutils in the uses clause.
However, when I insert hyieutils in the uses clause, the IDE opens IOPreviews.pas, sets the cursor on Graphics in the uses clause and the compiler complains:

[DCC Fatal error] IOPreviews.pas(32): F1026 File not found: 'Graphics.dcu'

But this should not be, as I use the ImageEn components in other VCL Form programs without problems.

I have Delphi XE2
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  10:03:00  Show Profile  Reply
It is impossible to determine what the problem is without seeing your code.

William Miller
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  10:07:37  Show Profile  Reply
In Project Options, I added "Vcl" in the "Unit Scope Names" list.

This solved the problem. So why doesn't the ImageEn installer do this?
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  10:35:57  Show Profile  Reply
Because not all versions of Delphi need the prefix... only the XE versions. There is something else wrong however, because I am running XE4 and the prefix is not needed to compile.

William Miller
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  11:24:32  Show Profile  Reply
There is another problem: Either ImageEnIO.LoadFromFile(APngFile) or ImageEnProc.CopyToClipboard() does something wrong, because:

This is the original image:



However, after copying it to the clipboard, it looks so:



So how can I make it look like the original image after loading and copying to the clipboard?
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  11:34:49  Show Profile  Reply
ImageEnView1.EnableAlphaChannel := True;
ImageEnView1.Proc.SetTransparentColors(TColor2TRGB(clBlack), TColor2TRGB(clBlack), 0);

You may also have to make sure the image is 32-bit with alpha channel and the transparent color is set before you copy to the clipboard:
ImageEnView.IO.Params.BitsPerSample := 8;
ImageEnView.IO.Params.SamplesPerPixel := 4;

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  11:36:13  Show Profile  Reply
It looks like it's the fault of ImageEnProc.CopyToClipboard(), because this code preserves the original image:

ImageEnIO.LoadFromFile(APngFile);
ImageEnIO.SaveToFilePNG('test.png');
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  11:38:27  Show Profile  Reply
Why do you always think that imageen is always causing the problem? It is not!

William Miller
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  11:45:05  Show Profile  Reply
So do I need to create a TImageEnView in memory, since EnableAlphaChannel and SetTransparentColors are members only of TImageEnView?
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  11:51:31  Show Profile  Reply
No... ImageEnView is for display...

But ImageEnProc1.SetTransparentColors is a TImageenProc not a TImageEnView.

ImageEnView1.Proc.SetTransparentColors uses a embedded copy of TImageEnProc so ImageEnView1.Proc.SetTransparentColors is the same as ImageEnProc1.SetTransparentColors.

If you are quite new to ImageEn then you should read and understand all you can about transparency in the forum and in the help file.

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 22 2014 :  12:15:20  Show Profile  Reply
Unfortunately, the original image is still not preserved after copying to the clipboard:

ThisImageEnView := TImageEnView.Create(nil);
try
  ThisImageEnView.IO.LoadFromFilePNG(ParamStr(1));

  ThisImageEnView.EnableAlphaChannel := True;
  ThisImageEnView.Proc.SetTransparentColors(TColor2TRGB(clBlack), TColor2TRGB(clBlack), 0);

  ThisImageEnView.IO.Params.BitsPerSample := 8;
  ThisImageEnView.IO.Params.SamplesPerPixel := 4;

  ThisImageEnView.Proc.CopyToClipboard(True);
finally
  ThisImageEnView.Free;
end;


EnableAlphaChannel is a member only in TImageEnView, so I have to use TImageEnView.

The original image of course is 32 bit with alpha channel.
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 22 2014 :  12:38:01  Show Profile  Reply
Post your code and I'll take a look at it.... all the code in your project... without seeing all the code there is no way to know what is causing the problem.

Is this a console app... if so, then do not use TImageEnView at all!

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 23 2014 :  02:30:04  Show Profile  Reply
This does the job by using TImage, as you said that I should not use TImageEnView in a console program.

However, the transparency gets lost when copying to the clipboard. So how can transparency be preserved?

program CopyImageFromFile;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  // CodeSiteLogging,
  Vcl.ExtCtrls,   // -> TImage
  Winapi.Windows, // -> HPALETTE
  Vcl.Clipbrd,
  //Vcl.Graphics,
  System.SysUtils;

procedure DoCopyImageFromFile(const APngFile: string);
var
  ThisImage: TImage;
  MyFormat: Word;
  Bitmap: TBitMap;
  AData: THandle;
  APalette: HPALETTE;
begin
  // CodeSite.Send('DoCopyImageFromFile: APngFile', APngFile);
  ThisImage := TImage.Create(nil);
  try
    ThisImage.Picture.LoadFromFile(APngFile);
    ThisImage.Picture.SaveToClipBoardFormat(MyFormat, AData, APalette);
    ClipBoard.SetAsHandle(MyFormat, AData);
  finally
    ThisImage.Free;
  end;
end;

begin
  try
    // Usage: CopyImageFromFile.exe test.png
    // test.png is 32 bit with alpha channel
    if ParamCount = 1 then
    begin
      if FileExists(ParamStr(1)) then
      begin
        if LowerCase(ExtractFileExt(ParamStr(1))) = '.png' then
          DoCopyImageFromFile(ParamStr(1));
      end;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 23 2014 :  06:47:55  Show Profile  Reply
Why are you using TImage? Can't you just use TImageEnIO and TImageEnProc instead of TImage?

William Miller
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 23 2014 :  07:26:14  Show Profile  Reply
I don't understand your questions: As I've demonstrated above, it does not work for my purpose. Have you even tried my examples?
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 23 2014 :  07:42:46  Show Profile  Reply
You should not use TImage. It is more difficult to control transparency with TImage than with ImageEn, so why not use TImageEn IO and TImageEnProc to do the work as it has much more capability than TImage.

This works perfectly here:
program CopyImageFromFile;

{ Copy a 32-bit png image with alpha channel to the clipboard while preserving the
  alphachannel.  If the copy is sucessful then  when you paste the image into
  TImageEnView with:

  if ImageEnView1.Selected then
  begin
    ImageEnView1.Proc.SelPasteFromClip(True);
    ImageEnView1.Update;
  end
  else
    ImageEnView1.Proc.PasteFromClipboard;

  the transparency (or the alphachannel) will be maintained. }

{$APPTYPE CONSOLE}
{$R *.res}

{ Note: To prevent compiler file not found problems In the IDE go to
  Project -> Options - > Delphi Compiler.  Look for SearchPath and add the path
  to ImageEn source: D:\Components\ImageEn }

uses
  Vcl.Clipbrd,
  System.SysUtils,
  ImageEnIO,
  ImageEnProc,
  hyieutils;

procedure DoCopyImageFromFile(const AFilename: string);
var
  iIEBitmap: TIEBitmap;
  iImageEnIO: TImageENIO;
  iImageEnProc: TImageEnProc;
begin
  iIEBitmap := TIEBitmap.Create;
  try
    iImageEnIO := TImageENIO.Create(nil);
    try
      iImageEnIO.AttachedIEBitmap := iIEBitmap;
      iImageEnIO.LoadFromFile(AFilename);
      iImageEnProc := TImageEnProc.Create(nil);
      try
        iImageEnProc.AttachedIEBitmap := iIEBitmap;
        { If UseInternalFormat is True, two bitmap are saved: one in standard
          DIB format and one in internal format which preserves pixelformat
          and alpha channel. }
        if iImageEnProc.CopyToClipboard(True) then
          Writeln(AFilename + ' was copied to the clipboard with transparency.')
        else
          Writeln(AFilename + ' copy to clipboard failed.')
      finally
        iImageEnProc.Free;
      end;
    finally
      iImageEnIO.Free;
    end;
  finally
    iIEBitmap.Free;
  end;
end;

begin
  try
    // Usage: CopyImageFromFile.exe test.png
    // test.png is 32 bit with alpha channel
    if ParamCount = 1 then
    begin
      if FileExists(ParamStr(1)) then
      begin
        if LowerCase(ExtractFileExt(ParamStr(1))) = '.png' then
          DoCopyImageFromFile(ParamStr(1));
      end;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 23 2014 :  09:53:21  Show Profile  Reply
William, after executing this code, try to PASTE the image from the clipboard into any graphics program or text processor: It does not work (i.e. transparency is not preserved) because your code creates a non-standard clipboard format which AFAIK is not recognized by any other program: IMAGEEN RAW FORMAT:



So how could your code be modified to create a clipboard format with alpha blend transparency recognized by standard programs? For example, it should be possible to paste it into MS Word, OO Writer, IrfanView and other graphics programs.
Go to Top of Page

w2m

USA
1990 Posts

Posted - Mar 23 2014 :  10:52:09  Show Profile  Reply
Two clipboard formats are saved. A DIB and a internal format. When I said the it works here I was pasting the clipboard into imageen so transparency was and is maintained.

With Microsoft Word I successfully pasted the image from the clipboard, but the background was black so I guess a DIB does not support the alphachannel. To get the image to appear correctly with a transparent background in Word all I had to do was to select Color->SetTransparentColor and the image was displayed correctly with a transparent background.

You can paste the clipboard content into Word, but not with transparency without some adjustment within Word.

I also tried to use TPngImage to copy the image to the clipboard but I can not figure out how to properly use it. The reason your version fails I think is because you can not just call
ThisImage.Picture.SaveToClipBoardFormat(MyFormat, AData, APalette)
with Myformat, AData and APalette undefined. You have to define MyFormat, AData and APalette before calling SaveToClipBoardFormat.

The same thing occurs when using TPNGImage:
procedure DoCopyPNGToClipboard(AFilename: string);
const
   MyClipboardFormatStr = 'PNG';
var
  iPNGImage: TPNGImage;
  iFormat: Word;
  iData: THandle;
  iPalette: HPALETTE;
begin
  iPNGImage := TPNGImage.Create;
  try
    iPNGImage.LoadFromFile(AFilename);
  finally
    iFormat := RegisterClipboardFormat(MyClipboardFormatStr);
    iPNGImage.SaveToClipBoardFormat(iFormat, iData, iPalette);
    ClipBoard.SetAsHandle(iFormat, iData);
    iPNGImage.Free;
  end;

  begin
    try
      // Usage: CopyPNGToClipboard.exe test.png
      // test.png is 32 bit with alpha channel
      if ParamCount = 1 then
      begin
        if FileExists(ParamStr(1)) then
        begin
          if LowerCase(ExtractFileExt(ParamStr(1))) = '.png' then
            DoCopyPNGToClipboard(ParamStr(1));
        end;
      end;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  end;
end;

I set the format, but not the iData or iPalette, so it does not function.

I searched the web for some sample code to figure out how to define those parameters, but I can find nothing. There is no code shown anywhere that I can find that shows how to do this including some extensive discussion at stackoverflow.com.

Meanwhile I'll continue experimenting with ImageEn, but for now I have no good answer for you.

Just a reminder. I do not work for ImageEn.

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Go to Top of Page

PeterPanino

933 Posts

Posted - Mar 23 2014 :  13:37:07  Show Profile  Reply
William, I have found a method to perfectly insert the image in MS Word via HTML FORMAT. However, I was not able to create the HTML FORMAT TOGETHER with the bitmap format in clipboard - only one or the other. Try the code
1. as it is
2. by uncommenting the DoCopyImageFromFile line
I would be glad if you know a method to put these formats together.

program CopyImageFromFile;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  Winapi.Windows,
  Vcl.Clipbrd,
  System.SysUtils,
  ImageEnIO,
  ImageEnProc,
  hyieutils;

procedure DoCopyImageFromFile(const APngFile: string);
var
  iIEBitmap: TIEBitmap;
  iImageEnIO: TImageENIO;
  iImageEnProc: TImageEnProc;
begin
  iIEBitmap := TIEBitmap.Create;
  try
    iImageEnIO := TImageENIO.Create(nil);
    try
      iImageEnIO.AttachedIEBitmap := iIEBitmap;
      iImageEnIO.LoadFromFile(APngFile);
      iImageEnProc := TImageEnProc.Create(nil);
      try
        iImageEnProc.AttachedIEBitmap := iIEBitmap;
        { If UseInternalFormat is True, two bitmap are saved: one in standard
          DIB format and one in internal format which preserves pixelformat
          and alpha channel. }
        if iImageEnProc.CopyToClipboard(True) then
          Writeln(APngFile + ' was copied to the clipboard with transparency.')
        else
          Writeln(APngFile + ' copy to clipboard failed.')
      finally
        iImageEnProc.Free;
      end;
    finally
      iImageEnIO.Free;
    end;
  finally
    iIEBitmap.Free;
  end;
end;

function FormatHTMLClipboardHeader(HTMLText: string): string;
const
  CrLf = #13#10;
begin
  Result := 'Version:0.9' + CrLf;
  Result := Result + 'StartHTML:-1' + CrLf;
  Result := Result + 'EndHTML:-1' + CrLf;
  Result := Result + 'StartFragment:000081' + CrLf;
  Result := Result + 'EndFragment:°°°°°°' + CrLf;
  Result := Result + HTMLText + CrLf;
  Result := StringReplace(Result, '°°°°°°', Format('%.6d', [Length(Result)]), []);
end;

procedure CopyHTMLAndImageToClipBoard(const str, APngFile: AnsiString; const htmlStr: AnsiString = '');
var
  gMem: HGLOBAL;
  lp: PChar;
  Strings: array[0..1] of AnsiString;
  Formats: array[0..1] of UINT;
  i: Integer;
  HTML: string;
begin
  gMem := 0;
  {$IFNDEF USEVCLCLIPBOARD}
  Win32Check(OpenClipBoard(0));
  {$ENDIF}
  try
    //most descriptive first as per api docs
    Strings[0] := FormatHTMLClipboardHeader(htmlStr);
    Strings[1] := str;
    Formats[0] := RegisterClipboardFormat('HTML Format');
    Formats[1] := CF_TEXT;
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(EmptyClipBoard);
    {$ENDIF}
    for i := 0 to High(Strings) do
    begin
      if Strings[i] = '' then Continue;
      //an extra "1" for the null terminator
      gMem := GlobalAlloc(GMEM_DDESHARE + GMEM_MOVEABLE, Length(Strings[i]) + 1);
      {Succeeded, now read the stream contents into the memory the pointer points at}
      try
        Win32Check(gmem <> 0);
        lp := GlobalLock(gMem);
        Win32Check(lp <> nil);
        CopyMemory(lp, PChar(Strings[i]), Length(Strings[i]) + 1);
      finally
        GlobalUnlock(gMem);
      end;
      Win32Check(gmem <> 0);
      SetClipboardData(Formats[i], gMEm);
      Win32Check(gmem <> 0);
      gmem := 0;
    end;

    // Uncomment this to copy ONLY the bitmap without transparency:
    //DoCopyImageFromFile(APngFile); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  finally
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(CloseClipBoard);
    {$ENDIF}
  end;
end;

var
  HTML: string;

begin
  try
    // Usage: CopyImageFromFile.exe test.png
    // test.png is 32 bit with alpha channel
    if ParamCount = 1 then
    begin
      if FileExists(ParamStr(1)) then
      begin
        if LowerCase(ExtractFileExt(ParamStr(1))) = '.png' then
        begin
          HTML := '<img border="0" src="file:///' + ParamStr(1) + '">';
          CopyHTMLAndImageToClipBoard('', ParamStr(1), HTML);
        end;
      end;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
Go to Top of Page
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
Jump To: