środa, lipiec 29, 2009

70-502 (WPF) - Image Metadata

Po przyjrzeniu się dokładniej co znajduje się w zmodyfikowanej liście rzeczy niezbędnych do egzaminu zauważyłem punkt, który dotychczas nie poruszyłem w kursie. Dotyczy on metadanych obrazków.

Bitmap metadata

Jak wiemy obrazki mogą zawierać wiele informacji je określających. Z takich podstawowych to chociażby autor, tytuł czy komentarz. Jednak informacji tych jest znacznie więcej. Szybki rzut okna na szczegóły zdjęcia w Explolerze pokaże nam jak wiele informacji może zdjęcie przechowywać.

Dobrze widzicie. Jest tego aż 4 strony.
Jak się możemy do tych informacji dostać?
WPF wprowadza kilka dodatkowych klas, za pomocą których dostęp do tych danych jest możliwy. Zobaczmy prosty przykład, który sobie omówimy:


var fs = new FileStream("pawel_lukasik_foto.jpg", FileMode.Open, FileAccess.Read, FileShare.Read);


BitmapDecoder decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.Default);


BitmapFrame frame = decoder.Frames[0];


var metadata = (System.Windows.Media.Imaging.BitmapMetadata)frame.Metadata;


Pominę omówienie linii pierwszej bo to chyba oczywiste. Kolejną czynnością, którą robimy jest stworzenie dekodera, który umożliwi nam dostęp do tych danych. Dekodera tworzymy za pomocą statycznej metody Create podając jako parametr nasz strumień. Pozostałe parametry to odpowiednio ustawienia tworzenia obiektu i cache'a. Mając tak stworzony obiekt możemy wyciągnąć z niego odpowiednią ramkę. Znajduje się ona pod indeksem 0. Wyciąganie ramki zrobione jest przy użyciu indeksera gdyż możliwe, że obrazek będzie zawierał więcej niż jedną ramkę metadanych. Po tym nie pozostaje nam już nic innego jak wyciągnąć metadane przy użyciu właściwości Metadata.

Pól jest naprawdę dużo i możemy ich po prostu użyć aby dostać się do tych danych


Array.ForEach(metadata.Author.ToArray(), Console.WriteLine);


Console.WriteLine(metadata.Rating);


Console.WriteLine(metadata.Comment);


Array.ForEach(metadata.Keywords.ToArray(), Console.WriteLine);


Console.WriteLine(metadata.Subject);


Co jeśli jednak znajdzie się właściwość, do której nie ma bezpośredniego dostępu? Tu przychodzi z pomocą MQL.

MQL

MQL to specjalny język (Metadata Query Language) stworzony z myślą o dostępie do tych danych. Wszystkie wartości za które wypisaliśmy za pomocą właściwości można by uzyskać za pomocą MQL'a. Omówienie języka znacznie wykracza poza ramy prostego posta, ale pokażmy sobie na przykładzie jak możemy odczytać jakąś właściwość:



if (metadata.ContainsQuery("/app1/ifd/{ushort=18246}"))


{


    var q = metadata.GetQuery("/app1/ifd/{ushort=18246}");


    Console.WriteLine(q.ToString());


}


Powyższy kod odczyta nam to samo, co właściwość Rating. Zapytanie składa się ze ścieżki do odpowiedniego bloku danych (/app1/ifd) oraz identyfikatora pola (/{ushort=18246}). Więcej na ten temat w linkach poniżej.

Za pomocą MQL da się też modyfikować parametry. W teorii powinno działać to tak:


var writer = frame.CreateInPlaceBitmapMetadataWriter();


writer.SetQuery("/app1/ifd/{ushort=18246}", 3);


writer.TrySave();


Dlaczego piszę "w teorii"?. Dlatego, że dla plików jpg z jakichś względów nie działa. Śledzę wątki na forach, aby dość jak to zrobić aby działało, ale na chwilę obecną nie znalazłem działającego rozwiązania.

Na dziś to tyle. Miłej zabawy z MQL'em.

Linki:

Metadata Query Language Overview
BitmapMetadata class
Specyfikacja formatu EXIF

wtorek, lipiec 28, 2009

200. post i konkurs

Oto 200. post na moim blogu. Trochę czasu zleciało (ponad 3 lata), aby go napisać ale udało się :).

Z tej racji postanowiłem przygotować mały konkurs dla czytelników. Można wygrać ciekawe nagrody (o tym poniżej). Wystarczy udzielić odpowiedzi na proste pytania.

  1. Ile razy na blogu pojawił się opis programu Deep Zoom Composer i jakie projekty były w ramach omówienia przygotowane?

  2. Jakie książki zostały zrecenzowane na blogu (+ linki)?

Odpowiedzi można słać na adres umieszczony w profilu. Wygrywają 2 pierwsze osoby. A do wygrania są: kubek dotnetomaniak (będę zamawiał, więc trochę potrwa) + koszulka Telerik (nie gwarantuje rozmiaru). I na koniec mała prośba - jeśli masz już taki kubek i koszulkę - daj szansę innym :)

sobota, lipiec 25, 2009

The back of the napkin - Recenzja

Po skończonej lekturze książki o Silverlight 2 (Foundation Silverlight 2 Animation) zabrałem się za czytanie czegoś lżejszego. The back of the napkin omawia zagadnienie, które autor określa jako 'visual thinking'. Polega ono na przekazywaniu wiedzy, idei oraz rozwiązywaniu problemów za pomocą obrazów (w zasadzie obrazków).

Z książki możemy dowiedzieć się na czym polega 'visual thinking', jaką przewagę daje nam to w stosunku do tradycyjnego opartego na tekście sposobu 'komunikacji' oraz w jaki sposób możemy zacząć naszą przygodę z tym.

Autor w bardzo obrazowy (a jakże :)) sposób przedstawia jak możemy jak rozpocząć używanie jego techniki. Krok po kroku omawia przykłady problemów oraz jak możemy w nich zastosować 'visual thinking'. Podaje także 6 kroków za pomocą których, każdy problem możemy sprowadzić do reprezentacji obrazkowej :).

Podsumowując - Książka lekka i przyjemna. Fajnie się ją czyta, a jeśli ktoś jest jeszcze zainteresowany rozwojem osobistym i poszerzaniem swoich możliwości to nada się dla niego jak ulał.

http://www.thebackofthenapkin.com/

Na przeczytanie czeka już następna książka - SQL Injection Attacs And Defense

piątek, lipiec 24, 2009

WPF - Podsumowanie

Myślę, że przyda się takie podsumowanie. Poniżej pełna lista omówionych tematów lekcji o WPF.
Jeżeli coś jeszcze dojdzie postaram się pamiętać, aby ją zaktualizować.

  1. Typy aplikacji
  2. Routed & Attached events
  3. Komendy
  4. PageBased navigation
  5. Page functions
  6. Ustawienia aplikacji
  7. Dispatcher
  8. Przyciski
  9. Kontenery (Label, ToolTip)
  10. GroupBox, Expander
  11. ListBox
  12. ListBox - sortowanie, grupowanie i filtrowanie
  13. ComboBox
  14. ListView
  15. TabControl, Menu
  16. TreeView, ToolBar, StatusBar
  17. Visibility, Padding & Margin, Height & Width
  18. Justowanie, Justowanie treści, FlowDirection
  19. Transformacje - Rotacje, Translacje, Przekrzywienia
  20. Canvas, StackPanel, WrapPanel, DockPanel
  21. Grid
  22. Integrate WinForms i WPF
  23. User Controls
  24. CustomControls
  25. Drawings
  26. Geometry
  27. Kształty za pomocą łańcuchów znaków, Pens
  28. Visuals
  29. Shapes
  30. Brushe
  31. Wstęp do 3D
  32. Transformacje 3D
  33. Światła
  34. FlowDocument
  35. Multimedia
  36. Zasoby
  37. DataBinding
  38. ValueConverters, DataTemplate
  39. Binding - Walidacja danych
  40. Style
  41. Triggers
  42. Animacje w C#
  43. Animacje w XAML
  44. Deplyoment

Dodatkowo:

70-502 (WPF) Przygotowania...nr 20 - Deployment

Po powrocie z Norwegii czas powrócić do pisania o WPF :).

Dziś krótka i prawdopodobnie jedna z ostatnich lekcji. Do omówienia zostało nam sposób dostarczenia naszej aplikacji do klienta.
Jakie zatem mamy opcje? Windows Installer oraz ClickOnce.

Nie będę za bardzo skupiał się na różnicach pomiędzy nimi, gdyż nie ma tu nic innego w stosunku do aplikacji WinForms. Warto przypomnieć tylko, że ClickOnce jest odpowiedni do środowisk 'partial-trust', uruchamianie z adresu zdalnego oraz ma wbudowany mechanizm aktualizacji.

Windows Installer

Aplikację napisaną w WPF możemy tak jak dotychczas dostarczyć za pomocą Windows Installera. Nie różni się to od znanego nam przypadku z WinForms. Warto tylko, zauważyć, iż nie bardzo ma sens dostarczanie aplikacji XBAP w ten sposób. Wymagałoby to, aby XBAP był uruchamiany w trybie 'full-trust', co z racji specyfikacji tego rozwiązania jest niemożliwe.

ClickOnce

Podobnie jak z Windows Installerem nie ma tu żadnej magii. Ustawienia ClickOnce'a dokonujemy z odpowiedniej karty w VisualStudio.
W przypadku aplikacji XBAP warto pamiętać, iż domyślnie jest uruchamiana w trybie Internet Zone przez co nie mamy dostępu do wielu dobrze znanych i lubianych funkcjonalności.

Podsumowanie

W zasadzie to by było na tyle. Podsumowując miało być 32 lekcje wyszło 20 :). Jednak w niektórych tematach są też omawiane inne, które na liście elementów do egzaminów pojawiają się w innym miejscu, ale ich omówienie w oderwaniu od innych tematów nie ma sensu. Czuję jednak, że jakiś temat jeszcze pominąłem jednak nie mogę w sieci znaleźć listy tematów, które egzamin pokrywa (strony Microsoftu rzucają 404 :( ). Tak więc być może powrócę z tematem WPF, ale teraz muszę się zastanowić nad jakimś nowym tematem do cyklu lekcji.
Wszelkie propozycje, uwagi czy też komentarze do tego cyklu mile widziane.

sobota, lipiec 18, 2009

CodeCamp w październiku?

Chyba większośc z nas zetknęło się z wydarzeniem CodeCamp. Jest to konferencja organizowana przez grupę KGD.NET.

Pojawiła się możliwość zorganizowania w tym roku jeszcze jednej konferencji z udziałem światowych gwiazdami naszego .NET-owego podwórka.

Jeśli chciałbyś aby to wydarzenie odbyło się zerknij pod poniższy link i wspomóż organizację CodeCamp w październiku - CodeCamp w październiku

sobota, lipiec 11, 2009

Deep Zoom Composer

Wczoraj (tj. 10.07.09) na świat wersja 3 Silverlight'a oraz Blenda (jak na razie w wersji RC). Trochę przed tymi wydarzeniami miała miejsce jeszcze jedna premiera o której trochę mniej pisze się. Chodzi mianowicie o kolejna wersja Deep Zoom Composer. Narzędzia do przygotowywania obrazów do funkcjonalności Deep Zoom dostępnej w Silverlight. Postanowiłem trochę podpatrzeć co zawiera najnowsza wersja.
Już pierwszy rzut oka na na ekran komponowania pokazuje zmiany.

Edytor



Po prawej lewej stronie widzimy standardową listę opcji umożliwiających aranżację zdjęć (dostępna była już w poprzedniej wersji). Po prawej jednak jest parę nowości. Wzrok przykuwa rozwijane menu z opcjami (Slideshow, Menu, Internal Links, External Links oraz Impressions. Omówimy je dokładniej w późniejszej części. Dodatkowo mamy jeszcze widok warstw oraz podstawowe informacje o zdjęciu - ścieżka, rozdzielczość, pole na tagi określające zdjęcie oraz coś nowego limity widoczności oraz tooltip.
Dodatkowo mamy możliwość dodania elementu Area. Umożliwia on zaznaczenia wybranego fragmentu obrazka do menu lub pokazu slajdów i następnie umożliwia przejście do wybranego fragmentu.

Pokaz slajdów

W tej wersji mamy możliwość stworzenia pokazu slajdów.

Dodając zdjęcia do specjalnej kolekcji i ustalając ich kolejność w prosty sposób wytworzymy animację z płynnymi przejściami pomiędzy nimi. Przydatne gdy chcemy pokazać. Przydałoby się jednak trochę więcej kontroli nad animacją (np. czas wyświetlania zdjęcia, czas przejścia itp.).

Menu

Kolejną nowością jest menu. Mamy możliwość dodania nawigacji do naszej sceny. Obrazki (i obszary) można dodać do listy z której następnie możemy wybrać interesujący nasz obrazek lub fragment. Przydatne jeśli nie chcemy szukać na scenie - możemy wybrać go z listy i od razu przejść do interesującego nas fragmentu.


Linki

Każdemu elementowi na naszej scenie możemy przypisać link. Linki mogą być zarówno zewnętrzne jak i wewnętrzne. Te pierwsze mogą prowadzić do dowolnego adresu URL, te drugie przekierowywać do innego elementu na scenie.

Śledzenie

Najnowsza wersja zawiera jeszcze jedną bardzo pożyteczną funkcjonalność. Umożliwia dodanie śledzenia częstotliwości wyświetlania danego obrazka. Opiera się ona na linkach. Definiujemy adres strony, które ma zostać wywołany (np. adres strony, która posiada zainstalowany skrypt Google Analitics).

Podsumowanie

Najnowsza wersja Deep Zoom Composera zawiera kilka przydanych nowości. Szczególnie śledzenie odwiedzin będzie przydatne do zastosowań bardziej komercyjnych (można badać, która cześć naszej sceny jest najczęściej odwiedzana).
Z negatywnych rzeczy można tylko wymienić, iż czasami przy eksporcie operacja zakańcza się bez żadnej informacji o błędzie, jednak kompozycja nie jest poprawnie przygotowana i nie można jej otworzyć.

Projekt

Pełny projekt do zobaczenia poniżej:



Do zobaczenia za mniej więcej tydzień. Na najbliższe dni ruszam troszkę bardziej na północ:



Wyświetl większą mapę

niedziela, lipiec 05, 2009

70-502 (WPF) Przygotowania...nr 19.1 - Animacje w XAML

W poprzednim odcinku pokazaliśmy sobie jak możemy stworzyć animacje w WPFie za pomocą C#. Dziś zobaczymy jak można to zrobić przy użyciu deklaratywnego języka XAML.

EventTrigger i Storyboard

Przy okazji omawiania triggerów, wspomniałem o EventTriggerach i ich zastosowaniu do animacji. Zobaczmy mały przykład jak zdefiniujemy dany trigger oraz Stroyboard.


<Button Content="Przycisk" x:Name="przycisk" Width="200">


    <Button.Triggers>


        <EventTrigger RoutedEvent="Button.Click">


            <EventTrigger.Actions>


                <BeginStoryboard>


                    <Storyboard>


                        <DoubleAnimation To="50" Storyboard.TargetProperty="Width" />


                    </Storyboard>


                </BeginStoryboard>


            </EventTrigger.Actions>


        </EventTrigger>


    </Button.Triggers>


</Button>


Omówmy poszczególne elementy krok po kroku:

Zaczynamy od zdefiniowania elementu EventTrigger i ustawienia jego właściwości RoutedEvent. Jego wartość ustawimy na Button.Click, zatem interesować nas będzie zdarzenia naciśnięcia przycisku. Następnie zdefiniujemy akcję, która się wykona, gdy nasze zdarzenie zajdzie. Robimy to w tagach EventTriggers.Actions. Zaczynamy od tagu BeginStoryboard a następnie definiujemy Storyboard. Storyboard zawiera animacje, zdefiniowane za pomocą klas XXXAnimation, które będą wykonywać się po zajściu zdarzenia.

Można by się zastanawiać, po co wprowadzać dodatkowo tag BeginStoryboard. Ma to swoje uzasadnienie. Animacją można rozpoczynać także odegranie dźwięku/filmu. Jeśli będziemy chcieli zatrzymać posłużymy się tagiem StopAnimation (przykład był przy omawianiu Multimediów). Stąd taka redundancja w tagach definiujących animację.

Do samej już animacji użyjemy klasy DoubleAnimation definiując jaką właściwość będziemy animować (Width) oraz końcową jej wartość(50).

Oczywiście tak samo jak w C# mamy dostępne właściwości za pomocą możemy kontrolować naszą animację. Dla przykładu ustawmy sobie AutoReverse oraz BeginTime.


<DoubleAnimation To="50" Storyboard.TargetProperty="Width"


                AutoReverse="True" BeginTime="0:0:1"/>



Rodzaje animacji

Dotychczas w przykładach posługiwaliśmy się klasą DoubleAnimation jednak jest sporo innych klas na potrzeby animacji prócz tej. Kilka przykładów:

  • In32Animation

  • ColorAnimation

  • PointAnimation

Dodatkowo są także dostępne animacje, które używają "klatek".

  • In32AnimationUsingKeyFrames

  • ColorAnimationUsingKeyFrames

  • PointAnimationUsingKeyFrames

  • StringAnimationUsingKeyFrames

Pokażmy jak możemy użyć tej ostatniej:


<StackPanel>


    <TextBlock Text="" x:Name="crawl" FontSize="22" HorizontalAlignment="Center"/>


    <Button Content="Przycisk" x:Name="przycisk" Width="200">


        <Button.Triggers>


            <EventTrigger RoutedEvent="Button.Click">


                <EventTrigger.Actions>


                    <BeginStoryboard>


                        <Storyboard>


                            <StringAnimationUsingKeyFrames Storyboard.TargetProperty="Text" Storyboard.TargetName="crawl">


                                <DiscreteStringKeyFrame Value="A long time ago" KeyTime="0:0:0" />


                                <DiscreteStringKeyFrame Value="in a galaxy far, far away..." KeyTime="0:0:3" />


                                <DiscreteStringKeyFrame Value="StarWars" KeyTime="0:0:7" />


                                <DiscreteStringKeyFrame Value="" KeyTime="0:0:11" />


                            </StringAnimationUsingKeyFrames>


                            <DoubleAnimation Storyboard.TargetProperty="FontSize" To="60"


                                            Storyboard.TargetName="crawl" BeginTime="0:0:7" Duration="0:0:2" />


                        </Storyboard>


                    </BeginStoryboard>


                </EventTrigger.Actions>


            </EventTrigger>


        </Button.Triggers>


    </Button>


</StackPanel>


Poszczególne klatki animacji definiujemy jako DiscreteStringKeyFrame podając jej wartość i czas kiedy ma się dana klatka pojawić. Po uruchomieniu, tekst w kontrolce będzie zmieniał się z godnie z definicją a dodatkowo przy ostatniej klatce zwiększy się rozmiar czcionki, użytej do wyświetlenia napisu do rozmiaru 60.

Na dziś tyle, choć na pewno temat nie jest wyczerpany. W następnym odcinku będzie jeszcze trochę o animacjach przy użyciu klatek. Jednak już teraz warto pobawić się animacjami, gdyż jest to coś czego wcześniej developerzy WinForms nie mieli w swoim warsztacie. Warto spędzić trochę czasu na zapoznanie się z tym.