Autor Beitrag
teamrocket0
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Mi 14.11.18 00:38 
Moin, teamrocket0 hier.

Für ein kleines Hilfsprogramm habe ich mir dummerweise eine Aufgabe ausgesucht, die wohl nicht ganz so leicht zu lösen scheint.

Ich möchte ein einfaches, ganz normales JPG-Bild in ein kleines Icon (.ico) umwandeln.
Ich habe das zuerst mit meinem bevorzugten Delphi 7 versucht, aber nach geraumer Zeit habe ich nur ein Icon von 16x16 Pixel herausbekommen, das zudem auch noch den Anschein erweckt, aus DOS-Zeiten zu stammen. Die Größe lässt sich nicht ändern, da jammert Delphi mir die Ohren voll. Ist also unbrauchbar....

Dann habe ich es mit Delphi 10.2 Tokyo versucht. Das habe ich auch irgendwie an einem Abend zusammengebastelt bekommen. Es funktioniert jetzt.
Ich kann ein *.jpg-Bild per Drag and Drop auf die Delphi-Anwendung ziehen und es wird im selben Verzeichnis ein Icon von 256x256 Pixel erstellt. Die Farben sind auch wie im Original. Alles super. Ja! Es kann sein, das das Seitenverhältnisse nicht stimmt. Aber ich möchte es nur verwenden um die Album-Cover als neue Ordnersymbole in die Desktop.ini einzutragen.

Was mich nur stört ist, das die Delphi 10.2 Anwendung für diese kleine Aufgabe einen 10MB großen Spielplatz braucht, währen die Delphi 7 Anwendung, die mittlerweile viel mehr Aufgaben erfüllt, lediglich 600Kb umfasst.

Jetzt die Frage...kann ich da was optimieren!?

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, StdCtrls, System.ImageList, Vcl.ImgList,
  Vcl.ExtCtrls, axCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
      procedure DragDrop(var Message: TWmDropFiles);
      message WM_DROPFILES;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses ShellApi;

procedure TForm1.FormCreate(Sender: TObject);
begin
 {Let Windows know we accept dropped files}
  DragAcceptFiles(Form1.Handle, True);
end;

procedure TForm1.DragDrop(var Message: TWmDropFiles);
var
Filename      : string;
OleGraphic    : TOleGraphic;
fs            : TFileStream;
Source        : TImage;
BMP           : TBitmap;
BmImg         : TBitmap;
BmpMask       : TBitmap;
IconInfo      : TIconInfo;
Ico           : TIcon;
begin
//Drag and Drop the Objekt to get the path
SetLength(Filename,2000);
DragQueryFile(Message.Drop,0,Pchar(Filename),2000);
Form1.Memo1.Lines.Add(Filename);
//load the image into the programm
OleGraphic := TOleGraphic.Create; {The magic class!}
fs := TFileStream.Create(Filename, fmOpenRead Or fmSharedenyNone);
OleGraphic.LoadFromStream(fs);
//copy it over...
Source := Timage.Create(Nil);
Source.Picture.Assign(OleGraphic);
//resize the image on your formular (TImage-Object from the Toolbar) just to check
Form1.Image1.Width:=Source.Picture.Width;
Form1.Image1.Height:=Source.Picture.Height;
//convert into Bitmap
BMP := TBitmap.Create;
bmp.Width := Source.Picture.Width;
bmp.Height := Source.Picture.Height;
bmp.Canvas.Draw(00, source.Picture.Graphic);
//show the image in your formular
Form1.Image1.Picture.Bitmap := bmp; {Show the bitmap on form}
//release
fs.Free;
OleGraphic.Free;
Source.Free;
//Copy the Bitmap
BmImg := TBitmap.Create;
BmImg.Assign(Bmp);
//resize the Bitmap
Bmp.SetSize(256,256);
SetStretchBltMode(Bmp.Canvas.Handle, HALFTONE);
StretchBlt(Bmp.Canvas.Handle, 00256256,BmImg.Canvas.Handle, 00, BmImg.Width, BmImg.Height, SRCCOPY);
BmImg.Free;
//
BmpMask := TBitmap.Create;
BmpMask.Canvas.Brush.Color := clRed;
BmpMask.SetSize(256256);
//Copy the Bitmap into the Icon
FillChar(IconInfo, SizeOf(IconInfo), 0);
IconInfo.fIcon := True;
IconInfo.hbmMask := BmpMask.Handle;
IconInfo.hbmColor := Bmp.Handle;
Ico := TIcon.Create;
Ico.Height:=256;
Ico.Width:=256;
Ico.Handle:=CreateIconIndirect(IconInfo);
//save the Icon to a file next to the source (Filename)
Ico.SaveToFile(ChangeFileExt(Filename,'.ico'));
// calls Destroy
Bmp.Free;
BmpMask.Free;
Ico.Free;
end;
end.


Ich bin eigentlich ganz froh, das ich das jetzt fertig aber, aber ich bin noch nicht ganz zufrieden. Ich würde mich freuen, wenn jemand da noch mal einen prüfenden Blick rauf werfen kann.....

Danke Leute.

Bis Datum

teamrocket0

_________________
To be forgotten is worse than death!
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 381
Erhaltene Danke: 67

Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
BeitragVerfasst: Mi 14.11.18 00:59 
Delphi10 braucht von Haus aus so viel Speicher - da kann man nicht viel machen (außer auf eine frühere Delphi-Version wie D7 umzusteigen)
Theoretisch gibt es hier schon irgendwo so ein Streckungsprogramm

Am besten kommt man vmtl, wenn man das resizing selbst implementiert - such am besten mal nach 'delphi resize image' oder 'smooth resize' - da solltest du was passendes finden, was auch unter D7 läuft.

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6324
Erhaltene Danke: 127

Windows 7 + Windows 10
Tokyo Prof + CE
BeitragVerfasst: Mi 14.11.18 08:21 
10 MB ist auch bei Tokyo für so eine kleine Anwendung viel.
Bist du beim Kompilieren vielleicht noch auf Debug? Falls ja, stell das auf Release um. Das sollten ein paar MB weniger sein.
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 381
Erhaltene Danke: 67

Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
BeitragVerfasst: Mi 14.11.18 15:44 
Vielleicht hilft es auch, einige Bibliotheken aus der uses Klausel rauszunehmen die du nicht brauchst. Ich weiß nicht ob überhaupt und wenn ja was die Delphi-Optimierung beim Kompilieren alles prüft, kürzt und streicht. Speziell nicht verwendete Funktionen und Klassen wären ja interesssant. Allerdings konnte ich da auf embarcadero nichts hilfreiches finden

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2296
Erhaltene Danke: 420

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Do 15.11.18 01:09 
Guten Abend teamrocket0,

"dein zusammengebasteltes" Projekt sieht dem hier verblüffend ähnlich. :gruebel:
Verbessern lässt sich einiges, u.a. die fehlenden try-finally Blöcke, für dich sinngemäß:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
objectA := TObjectA.Create;
try
  //...
  objectB := TObjectB.Create;
  try
    //... usw.
  finally
    objectB.Free;
  end
finally
  objectA.Free;
end;

Außerdem hast du, wie der Poster, folgendes nicht bedacht:

CreateIconIndirect() hat folgendes geschrieben:
Remarks
[...] When you are finished using the icon, destroy it using the DestroyIcon function.

Wenn du das Projekt noch schmäler machen möchtest, deklariere jene WinAPI Funktionen, die für das Projekt von Nutzen sind, in eine eigene Unit und rufe diese von dort auf.
Somit reduzierst du es auf ein Minimum und hast eine bessere Übersicht.
Im Projekt selbst dürften die Units "Graphics" und "jpeg" von Relevanz sein, und alles andere kommt ganz auf deine Steuerelemente an.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8404
Erhaltene Danke: 417

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.2 CE
BeitragVerfasst: Do 15.11.18 11:58 
Wenn das Ding schon so 10MB hat, dann hast du mit ziemlicher Sicherheit noch im Debug-Modus. Ich bin mit meinem Player jetzt auch auf Tokyo umgestiegen, und die exe ist unter 8MB groß. Und da ist der VirtualTree als Komponente mit drin, Indy (HTTP-Server und Client), gnuGetText für Mehrsprachigkit, MadExcept für Fehlerbehandlungen und einiges mehr

Eine Routine, um aus großen Cover-Bildern kleine zu machen, ist auch mit drin. Allerdings nicht zu Ico, sondern zu jpg. Aber die Ico-Klasse dürfte das kaum so fett machen.

Falls du das mit dem Seitenverhältnis noch hinbekommen willst, kannst du einen Blick in meinen Code werfen:
github.com/DanielGau.../src/CoverHelper.pas , Funktion SafeResizedGraphic. Wobei man das ggf. anpassen muss, falls Icos quadratisch sein müssen (muss das? Keine Ahnung :gruebel:).

_________________
Oel ngati kameie.

Für diesen Beitrag haben gedankt: teamrocket0
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Fr 16.11.18 00:26 
Erst mal an Frühlingsrolle.

Ja, ich habe einen Großteil von dem Quellcode dort zusammen gerobt. Aber so wie er dort zu finden war hat er irgendwie nicht funktioniert, so wie ich es brauchte.

Am Quellcode kann ich nichts kleiner machen. ich habe die Converter-Prozedur bereits in eine eigene umgebaut und rufe diese zwei mal im Programm auf. Habe also da schon was gespart.

Was dieses "Try-Finally" angeht. Das Prog soll nicht Try'en, es soll machen.^^ Ansonsten. Ja. Die waren drin, ich habe sie ausgebaut.
DestroyIcon!? Ich weiß jetzt nicht ganz genau wozu, aber ih hek das aus und werde es hinzufügen.


@Gausi:

Es scheint so, das sich das Prog tatsächlich im "Debug-Modus" befindet, denn die ausführbare Datei befindet sich in einem Ordner namens "Debug". Nur weiß ich nicht, wie ich eben jenen "Debug-Modus" ausschalte. Bin erst vor 3 Tagen auf Delphi 10.2 umgestiegen.

Ich möchte diesen jpg to ico-Converter nur noch etwas kleiner machen und dann reicht mir das schon für mein Unterfangen aus. Den Rest konstruiere ich mir wieder in Delphi 7 zusammen. Damit komme ich besser klar... Den Converter rufe ich mir über mein anderes Prog mit 2 weiteren Parametern nur für diesen ICO-Mist auf.

Das Seitenverhältnis ist relativ egal. Ich gehe davon aus, das die Cover-Bilder des jeweiligen Albums immer quadratisch sind. Zumal ich das Icon ja nur als Ordnersymbol haben möchte. Das sollte also vollkommen ausreichend sein.
Mein alter Lehrer sagte mal: Nur so genau wie nötig. Nicht so genau wie möglich!. Von daher, alles gut. :-)

Soweit erst mal. Ich schau mal, was für Bibliotheken ich da noch auswerfen kann, und vor allem wie...

Bis Datum

teamroket0

_________________
To be forgotten is worse than death!
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Fr 16.11.18 00:28 
Ach, wo ich hier gerade wieder den guten alten Gausi sehe. Verdammt. Du hast mir schon so unglaublich oft geholfen. Danke man. :-)

Und wie es der Zufall so will fuchtle ich gerade mit der "mp3fileutils_06_lazarus" von dir herum. Ich möchte das irgendwie in mein Prog einbauen. Mal sehen ob ich das schaffe...

Gruß teamrocket0

_________________
To be forgotten is worse than death!

Für diesen Beitrag haben gedankt: Gausi
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Fr 16.11.18 00:45 
Und noch mal @Frühlingsrolle:

Wow, das mit dem...
ausblenden Delphi-Quelltext
1:
DestroyIcon(ico.Handle);					

...hat tatsächlich etwas gebracht. Nach zwei Icon's wurde das JPG immer mit dem ico überschrieben....

Das...
ausblenden Delphi-Quelltext
1:
Ico.Free;					

...hat es nicht gebracht. Nicht schlecht, Danke man. :-)

_________________
To be forgotten is worse than death!
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Fr 16.11.18 01:07 
Ahhh, OK...ich habe den "Release-Modus" gefunden. Mann kann ihn rechts bei der Projektverwaltung auf dem Icon das aussieht wie ein "Windows-Fenster mit Zahnrad und grünem Häkchen" umschalten. Man, das gab es früher alles nicht.

Aber gut. Somit ist das Prog nur noch 2MB groß. Damit kann ich schon leben.

_________________
To be forgotten is worse than death!
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2296
Erhaltene Danke: 420

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 16.11.18 13:50 
user profile iconteamrocket0 hat folgendes geschrieben:
Was dieses "Try-Finally" angeht. Das Prog soll nicht Try'en, es soll machen.^^ Ansonsten. Ja. Die waren drin, ich habe sie ausgebaut.

Das ist schlecht.
Sollte eine Zeile der Routine einen Fehler verursachen, hört das Programm an der Stelle auf und kommt erst garnicht zum .Free!
D.h. deine Anwendung verursacht ein Speicherleck.

user profile iconteamrocket0 hat folgendes geschrieben:
DestroyIcon!? Ich weiß jetzt nicht ganz genau wozu, aber ih hek das aus und werde es hinzufügen.

Gut, dass du es doch noch hinzugefügt hast.
Wie bereits verlinkt und zitiert, heißt es, dass man jenes Icon, welches man nicht mehr benutzt, im Anschluss mit DestroyIcon() freigeben soll, nachdem die Funktion CreateIconIndirect() aufgerufen wurde.

Ein gutgemeinter Rat: Wenn du es mit dir unbekannten WinAPI Funktionen zu tun bekommst, suche in der MSDN Doku danach, lies dir den jeweiligen Artikel grob durch und lege deine Aufmerksamkeit auf die einzelnen Parameter Beschreibungen, die möglichen Rückgabewerte (Return Values) - wichtig bei der Fehlererkennung, und vorallem auf die Hinweise/Bemerkungen (Remarks).
Ob du einen Quelltext übernimmst, das kümmert niemanden. DU musst verstehen, was da vor sich geht. ;)

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: Sa 17.11.18 00:55 
Die Quelltexte schau ich mir genau an, bevor ich sie einbaue. Ich muss ja schließlich damit klar kommen. Und wenn ich es nicht verstehe, dann knack ich das Ding, oder ich such was anderes...^^

Try and Finally mögen ja ihre Berechtigungen haben. Aber bei dem kurzen Prog sollte es keine Fehler geben.

Im ersten Probelauf habe ich aus 50 jpg-Bildern auch 50 Icons gebastelt. Das läuft super!^^
Ich probiere es übers Wochenende noch mal mit paar anderen Datei-Typen und werde die Filtern, welche nicht verarbeitet werden können.

Soweit aber schon mal Danke für Eure Meinungen. :-)

Bis Datum

teamrocket0

_________________
To be forgotten is worse than death!
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2296
Erhaltene Danke: 420

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 17.11.18 18:11 
Auf deine Verantworung. :zustimm:
Im Netz schwirrt ein Delphi-Beispiel herum, welches zich mal kopiert und für Gut befunden wurde, hier.
Ähnliches gilt auch in C++, wobei dort auf:
- ImageList_LoadBitmap
- ImageList_GetIcon
- ImageList_Destroy
zugegriffen wird. Das Prinzip ist dasselbe.
Und auch hier auf das DestroyIcon() nicht vergessen!

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
teamrocket0 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 168
Erhaltene Danke: 1

Win ME, Win XP, Win 7, Win 10
Delphi 7, 10.2 Tokyo
BeitragVerfasst: So 18.11.18 00:25 
Oh, der ist aber schön kurz. Nur fehlt mir da wieder die Umwandlung von jpg in bmp.^^

_________________
To be forgotten is worse than death!
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2296
Erhaltene Danke: 420

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: So 18.11.18 02:18 
Wie wärs mit: bmp.Assign(jpg);

Ich hätte auch ein Beispiel zur Verfügung:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
uses 
  Windows, Classes, Graphics, jpeg;

// Skaliert die Zielgrafik (Target) proportional, egal wie die Quellgrafik (Src) vorliegt
procedure ScaleProp(Src, Target: TBitmap; NewWidth, NewHeight: Integer);
var
  w, h, l, t: Integer;
  f: Single;
begin
  if Src.Width > Src.Height then
    f := NewWidth / Src.Width else
    f := NewHeight / Src.Height;

  w := Round(Src.Width * f);
  h := Round(Src.Height * f);
  l := (NewWidth - w) div 2;
  t := (NewHeight - h) div 2;

  Target.PixelFormat := Src.PixelFormat;
  Target.Width := NewWidth;
  Target.Height := NewHeight;
  Target.Canvas.StretchDraw(Rect(l, t, w + l, h + t), Src);
end;

procedure JpegToIcon(Src, Target: string; NewWidth, NewHeight: Integer);
var
  jpg: TJpegImage;
  bmpSrc, bmpTarget: TBitmap;
  ico: TIcon;
  icoInfo: TIconInfo;
begin
  jpg := TJpegImage.Create;
  try
    jpg.LoadFromFile(Src);
    bmpSrc := TBitmap.Create;
    try
      bmpSrc.TransparentMode := tmAuto;
      bmpSrc.Width := jpg.Width;
      bmpSrc.Height := jpg.Height;
      bmpSrc.Assign(jpg);
      bmpTarget := TBitmap.Create;
      try
        ScaleProp(bmpSrc, bmpTarget, NewWidth, NewHeight);
        ico := TIcon.Create;
        try
          icoInfo.fIcon := true;
          icoInfo.hbmMask := bmpTarget.Handle;
          icoInfo.hbmColor := bmpTarget.Handle;
          icoInfo.xHotspot := 0;
          icoInfo.yHotspot := 0;
          ico.Handle := CreateIconIndirect(icoInfo);
          ico.SaveToFile(Target);
        finally
          DestroyIcon(ico.Handle);
          ico.Free;
        end;
      finally
        bmpTarget.Free;
      end;
    finally
      bmpSrc.Free;
    end;
  finally
    jpg.Free;
  end;
end;

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)