Jump to content
Tntman

Mixed resources type 12

Recommended Posts

Hi, I am making VCL app but I am mixing FMX units in it. Reason why I am mixing FMX units is that i wanted to detect if webCamera exist, I am using this tutorial ( official embarcadero sample )  to detect it and display useful information ( resolution and fps options ) that camera have:

 

http://docwiki.embarcadero.com/CodeExamples/Rio/en/FMX.CameraComponent_Sample

 

This example works fine even in VCL app, but there are some errors and warnings that i am getting when compiling application.. Again, I have to say that it compile with success and it works im just wondering is there any way to fix this issues and warning and should i do ( approach this ) differently ?

 

I know that it is bad to mix VCL and FMX , but unit "FMX.MEDIA" is such a nice unit that gives me a lot of nice features and i cant see similar unit in VCL...

I have to mention that I am actually not mixing VISUAL components on form, I am just using only VCL components with FMX.Media unit and methods from it..

 

Here is error pic: It basically says that it is keeping FMX resources and discarding VCL one

wsertegrtgrtrtg.thumb.png.409a7db35bca477dd084cb003f31d344.png

 

Also I have to say that when i comment FMX.Media unit and other places where I am using its code i stop receiving warnings during compiling.. It is obvious that those warnings are because i used FMX.Media unit..

Edited by Tntman

Share this post


Link to post
4 hours ago, David Heffernan said:

Wouldn't it just be easier to detect the webcam without trying to mix FMX into the system?

IT is too difficult for me to figure out and understand code  samples that i found on the internet for accessing webcamera on windows ( VCL ) .. 

I am making some sort of twitch bot/streaming application where i plan to exchange data bettwen users and twitch API + Twitch IRC . In my app i want to have feature for user ( streamer ) to have a nice preview what options he have on his camera ( resolution,fps etc ), also I want to add some features like taking a screenshot of his game that he is playing or whole screen,

 

I have 3 options, to make FMX or VCL app.

 

If i want to make FMX app it will be tricky to take screenshot of particular window or whole screen with fmx due to fmx.bitmap nature.. I basically cannot assing bitmap.canvas.handle when i want to take a screenshot.

 

Quote

DCDesk := GetWindowDC(GetDesktopWindow);
  BitBlt(bmpVCL.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DCDesk, 0,
    0, SRCCOPY);

this piece of code is impossible if using bmp from FMX.Graphics. So i have to take screenshot with VCL.Graphics.. SO  that means that i am using VCL units in my FMX project ( Mixing again .... )

 

Other option is to make VCL app that will do screenshot as it usually do with VCL.Graphics bitmap. And to use FMX.Media for accessing webcam properties .. ( Mixing again ... )

 

Third option is to Make VCL app and LEARN how to access camera options in VCL <- Hardest part ( not mixing fmx and vcl ) .... I guess that third option is best way to go and I think that i should try to re-learn and figure out how code that I found online works.. 

Share this post


Link to post

Accessing camera has nothing to do with VCL or FMX. It should be feasible to copy what FMX.Media.TCameraComponent is basically doing (trimming all the FMX part) and make you own simple component for VCL.

At least that's what I would do.

Share this post


Link to post
1 hour ago, Cristian Peța said:

Accessing camera has nothing to do with VCL or FMX. It should be feasible to copy what FMX.Media.TCameraComponent is basically doing (trimming all the FMX part) and make you own simple component for VCL.

At least that's what I would do.

I was thinking the same, but isn't a delphi compiler doing that behind the scenes ? ( trimming unused code ) ?

Share this post


Link to post

TCameraComponent  is using FMX.Graphics.TCanvas and you should replace with Vcl.Graphics.TCanvas and so on.

Look what TCameraComponent is doing and do the same using Vcl units.

Some things are not the same but with some work I think it should be doable.

Edited by Cristian Peța

Share this post


Link to post

I reorganized my code, im now explicitly assigning values from different units. For example bitmapVCL : vcl.graphic.bitmap... Bitmapfmx : fmx.graphic.bitmap and so on... And it is working perfectly fine..

 

I think i will not have errors in my program if i am not adding visual components like memo from vcl and memo from fmx 

 

But i will consider learning/remaking units.. 

 

 

Edited by Tntman

Share this post


Link to post
1 hour ago, Tntman said:

IT is too difficult for me to figure out and understand code  samples that i found on the internet for accessing webcamera on windows ( VCL ) .. 

There are numerous examples and tutorials online for how to work with webcams using the Win32 API.

1 hour ago, Tntman said:

In my app i want to have feature for user ( streamer ) to have a nice preview what options he have on his camera ( resolution,fps etc )

That information is accessible via webcam APIs.  You don't need VCL or FMX for that.

1 hour ago, Tntman said:

this piece of code is impossible if using bmp from FMX.Graphics. So i have to take screenshot with VCL.Graphics.. SO  that means that i am using VCL units in my FMX project ( Mixing again .... )

Or, you could simply take the screenshot using an in-memory GDI bitmap, and then copy the raw pixel data from that bitmap into an FMX TBitmap as needed.  Look at CreateCompatibleDC(), CreateCompatibleBitmap(), GetObject(), and TBitmap.Canvas.MapBitmap()/UnmapBitmap().

  • Thanks 1

Share this post


Link to post
1 hour ago, Remy Lebeau said:

That information is accessible via webcam APIs.  You don't need VCL or FMX for that.

I know but win api is too difficult for me, but i need to learn it eventually ..

 

1 hour ago, Remy Lebeau said:

Or, you could simply take the screenshot using an in-memory GDI bitmap, and then copy the raw pixel data from that bitmap into an FMX TBitmap as needed.  Look at CreateCompatibleDC(), CreateCompatibleBitmap(), GetObject(), and TBitmap.Canvas.MapBitmap()/UnmapBitmap().

I did not even know that this exist, it is really interesting i will definitely take a look into it, thanks

 

BTW, do you know why we have such a difference in size when SS is saved? 

 

Here is the code :

 

procedure unasit3();
var
  DCDesk: hdc;
  bmpVCL, test: VCL.Graphics.TBitmap;
  bmpFMX: FMX.Graphics.TBitmap;
  // bmpVCL -> MS -> MS -> bmpFMX
  MS: TMemoryStream;
begin
  bmpVCL := VCL.Graphics.TBitmap.Create;
  bmpVCL.PixelFormat := pf4bit;
  bmpFMX := FMX.Graphics.TBitmap.Create;

  MS := TMemoryStream.Create;

  bmpVCL.Height := Screen.Height;
  bmpVCL.Width := Screen.Width;

  DCDesk := GetWindowDC(GetDesktopWindow);
  BitBlt(bmpVCL.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DCDesk, 0,
    0, SRCCOPY);

  bmpVCL.SaveToStream(MS);
  MS.Position := 0;
  bmpFMX.LoadFromStream(MS);

  bmpFMX.SaveToFile('unit3FMXBITMAP.png'); 
  bmpVCL.SaveToFile('unit3VCLBITMAP.png');
  bmpVCL.Free;
  bmpFMX.Free;
  MS.Free;
end;

VCL Bitmap have 1.31 MB

FMX Bitmap have 79 KB 

 

Thats size on disk .. When I open images they look 100% the same , i cant see the difference in quality  even if i zoom in .. is there any explanation for that strange behavior ?

Share this post


Link to post
6 minutes ago, Tntman said:

is there any explanation for that strange behavior ?

The FMX bitmap that you save is a compressed bitmap. The VCL bitmap is a Windows bitmap, uncompressed. 

  • Thanks 1

Share this post


Link to post
5 hours ago, Tntman said:

BTW, do you know why we have such a difference in size when SS is saved? 

VCL's TBitmap supports only the BMP format (and actual BMPs, not JPEG/PNG-encoded BMPs that recent Windows versions support).  Saving a VCL TBitmap to a file with a ".png" extension DOES NOT create a PNG image, it creates a BMP image.  PNG is compressed, whereas BMP is (usually) not (though VCL's TBitmap can load a compressed BMP - I think - but it does not produce compressed BMPs).

 

FMX's TBitmap supports many formats, including BMP and PNG.  Saving an FMX TBitmap to a file with a ".png" extension creates a real PNG image.  Try saving your FMX TBitmap to a file with a ".bmp" extension and you will see a result closer to what VCL's TBitmap creates.

Quote

When I open images they look 100% the same

BMP and PNG are both lossless formats.  The pixel data in both formats may represent the same color arrangements to a viewer, but the way the data is stored in memory and in a file are very different.

Edited by Remy Lebeau

Share this post


Link to post
On 5/15/2020 at 12:04 AM, Tntman said:

I know but win api is too difficult for me

Then probably what I proposed (to adapt the component from FMX to VCL) is also too difficult for you.

 

On 5/15/2020 at 12:04 AM, Tntman said:

BTW, do you know why we have such a difference in size when SS is saved? 

uses
  Vcl.Imaging.pngimage;

procedure SaveBitmapToPNG(ABitmap: TBitmap; const AFileName: String; ACompresionLevel: Integer = 7);
var
  img: TPngImage;
  strm: TFileStream;
begin
  img := nil;
  strm := TFileStream.Create(AFileName, fmCreate);
  try
    img := TPngImage.Create;
    img.CompressionLevel := ACompresionLevel;
    img.Assign(ABitmap);
    img.SaveToStream(strm);
  finally
    strm.Free;
    img.Free;
  end;
end;

Here TBitmap is a Vcl.Graphics.TBitmap
 

Edited by Cristian Peța

Share this post


Link to post

All VCL TGraphic-derived classes have a SaveToFile() method, you don't need to save to a TFileStream manually:

uses
  Vcl.Imaging.PngImage;

procedure SaveBitmapToPNG(ABitmap: TBitmap; const AFileName: String; ACompresionLevel: Integer = 7);
var
  img: TPngImage;
begin
  img := TPngImage.Create;
  try
    img.CompressionLevel := ACompresionLevel;
    img.Assign(ABitmap);
    img.SaveToFile(AFileName);
  finally
    img.Free;
  end;
end;

 

Edited by Remy Lebeau

Share this post


Link to post

You are right, I didn't noticed. I made this procedure in a hurry from my code and there I need to save to a stream.

Share this post


Link to post

Guys, I am sorry. I had problems IRL, i abandoned all of my projects, I did not had time to play with them , but I will be back soon I guess and resume coding :classic_cheerleader:

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×