Author |
Topic |
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 08:52:36
|
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
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 09:47:52
|
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 |
|
|
w2m
USA
1990 Posts |
Posted - Mar 22 2014 : 10:03:00
|
It is impossible to determine what the problem is without seeing your code.
William Miller |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 10:07:37
|
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? |
|
|
w2m
USA
1990 Posts |
Posted - Mar 22 2014 : 10:35:57
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 11:24:32
|
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? |
|
|
w2m
USA
1990 Posts |
Posted - Mar 22 2014 : 11:34:49
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 11:36:13
|
It looks like it's the fault of ImageEnProc.CopyToClipboard(), because this code preserves the original image:
ImageEnIO.LoadFromFile(APngFile);
ImageEnIO.SaveToFilePNG('test.png'); |
|
|
w2m
USA
1990 Posts |
Posted - Mar 22 2014 : 11:38:27
|
Why do you always think that imageen is always causing the problem? It is not!
William Miller |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 11:45:05
|
So do I need to create a TImageEnView in memory, since EnableAlphaChannel and SetTransparentColors are members only of TImageEnView? |
|
|
w2m
USA
1990 Posts |
Posted - Mar 22 2014 : 11:51:31
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 22 2014 : 12:15:20
|
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. |
|
|
w2m
USA
1990 Posts |
|
PeterPanino
933 Posts |
Posted - Mar 23 2014 : 02:30:04
|
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. |
|
|
w2m
USA
1990 Posts |
Posted - Mar 23 2014 : 06:47:55
|
Why are you using TImage? Can't you just use TImageEnIO and TImageEnProc instead of TImage?
William Miller |
|
|
PeterPanino
933 Posts |
Posted - Mar 23 2014 : 07:26:14
|
I don't understand your questions: As I've demonstrated above, it does not work for my purpose. Have you even tried my examples? |
|
|
w2m
USA
1990 Posts |
Posted - Mar 23 2014 : 07:42:46
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 23 2014 : 09:53:21
|
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. |
|
|
w2m
USA
1990 Posts |
Posted - Mar 23 2014 : 10:52:09
|
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 |
|
|
PeterPanino
933 Posts |
Posted - Mar 23 2014 : 13:37:07
|
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. |
|
|
Topic |
|
|
|