NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: PropertyItem (class Image) - jak vytvořit novou instanci?

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Radek Chalupa:23.5.2017 8:26

Zdravím,
nechápu proč třída PropertyItem nemá public konstruktor a nelze tedy vytvořit její novou instanci. v MSDN se praví že je určena k přečtení a modifikaci existujícího exif tagu, ale nikoliv vytvoření nového??? Přitom v nativní aplikaci v c++ je v GDI+ stejná třída kterou lze normálně vytvořít (Gdiplus::Pro­pertyItem* pitem = new Gdiplus::Proper­tyItem();) a vytvořit tak nový exif tag i v souboru, který žádné exif tagy neobsahuje (to mám vyzkoušené).
V .NET tak musím získat existující tag (GetPropertyItem), ten modifikovat (změnit id) a zapsat (SetPropertyItem). Ale pokud v souboru žádný exif tag není, jediné řešení na které jsem příšel je načíst do jiné Bitmap jiný soubor, ve kterém nějaký exif určitě je a ten opět modifikovat a zapsat. Ovšem tohle "řešení" mi přijde tak úchylné, že při pomyšlení že bych to použil v softwaru který bych nějak prezentovat (ať komerčně nebo freeware) mi naskakuje husí kůže:-(
Nápadá někoho nějaké normální řešení jak zapsat nový exif tak do souboru (v "čistém" C#/NET, jinak si samozřejmě umím na to napsat DLL-ku v nativním c++).

Radek Chalupa
www.radekchalupa.cz

 
Odpovědět
23.5.2017 8:26
Avatar
HONZ4
Člen
Avatar
Odpovídá na Radek Chalupa
HONZ4:24.5.2017 21:23

Teď jsem to hledal, a je to vážně debilní, dokonce i na MSDN radí použít jiný soubor, který už PropertyItem obsahuje.

It is difficult to set property items, because the PropertyItem class has no public constructors. One way to work around this restriction is to obtain a PropertyItem by retrieving the PropertyItems property value or calling the GetPropertyItem method of an Image that already has property items. Then you can set the fields of the PropertyItem and pass it to SetPropertyItem.

Editováno 24.5.2017 21:24
 
Nahoru Odpovědět
24.5.2017 21:23
Avatar
termostat
Člen
Avatar
termostat:25.5.2017 8:45

Běžným způsobem to nepůjde.

using System.Runtime.Serialization;
...
var newItem = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
 
Nahoru Odpovědět
25.5.2017 8:45
Avatar
Odpovídá na termostat
Radek Chalupa:25.5.2017 9:02

Na tohle jsem mezitím taky narazil. Vypadá že funguje, otázka je zda tenhle způsob vytvoření instance nebude mít nějaké "vedlejší efekty" (memory leaky např.) - v MSDN píšou že neproběhne konstruktor, což by v tomhle případě nevadilo, ale zda proběhne dealokace ....

 
Nahoru Odpovědět
25.5.2017 9:02
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na Radek Chalupa
Jan Vargovský:25.5.2017 10:55

Jestli jde o System.Drawin­g.Imaging.Pro­pertyItem, tak v konstruktoru se nic neděje.

Záleží jak často to chceš vytvářet, jestli často, tak bych si na to udělal asi nějakou factory, která by si aspoň uchovávala ty data k reflexi - typeof(Proper­tyItem).GetCon­structor(...) a ten pak normálně zavoláš pro naplnění.

Jestli ti nevadí další dll, které dělá jen tuhle blbost, tak si to klidně napiš v c++ :)

 
Nahoru Odpovědět
25.5.2017 10:55
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.