Nummen kirkonkylä

  Pääsivulle  |  TIETOTEKNIIKAN PÄÄSIVULLE

Kuvan näyttäminen ikkunassa (WPF)

Seuraavassa on ensin ikkunan kuvaus xaml-tiedostona ja sen jälkeen C#-koodi, joka tulee omaksi tiedostokseen. Siinä on kuvattu ikkunan toiminnallisuudet. Kuva voidaan näyttää pikselitarkkana tai ikkunan kokoisena. Ikkunan kokoa voidaan muuttaa. Mukana on myös funktio, joka tarkistaa exif-tiedoista pitääkö kuvaa kiertää.

<!-- 14.11.2017  MainWindow.xaml -->
<Window x:Class="KuvaikkuWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:KuvaikkuWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="625">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="32" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel  Grid.Row="0"  Orientation="Horizontal" Margin="4"
                    Height="24" VerticalAlignment="Top" >
            <Button FontWeight="Bold" Content=" Alkuperäinen "
                PreviewMouseLeftButtonUp="ButtonAlku_Click" Margin="30,2,0,0"/>
            <Button FontWeight="Bold" Content="  Sovita  "
                PreviewMouseLeftButtonUp="ButtonSovi_Click" Margin="30,2,0,0"/>
        </StackPanel>

        <DockPanel Grid.Row="1" >
            <ScrollViewer Name="Skrolli" HorizontalScrollBarVisibility="Auto"
                VerticalScrollBarVisibility="Auto" >
                <Image  x:Name="esikuva" HorizontalAlignment="Left"
                    Margin="3,5,0,0" VerticalAlignment="Top"
                   SnapsToDevicePixels="True"  />
            </ScrollViewer>
        </DockPanel>

    </Grid>
</Window>

*************************************************************************
// 14.11.2017  
MainWindow.xaml.cs    (KuvaikkuWPF)
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
//using System.Windows.Data;
//using System.Windows.Documents;
using System.Windows.Input;
//using System.Windows.Media;
using System.Windows.Media.Imaging;
//using System.Windows.Navigation;
//using System.Windows.Shapes;

// Esimerkki miten ikkunassa näytetään kuva
// Kuva voidaan näyttää ikkunan kokoisena tai pixelitarkkuudella
// Tarvittaessa kääntää kuvan oikeaan asentoon käyttäen exif-dataa
// Windows Presentation Format (WPF), dotnet Framework 4.7
// Softa koodattu: Windows 8.1, Visual Studio Community 2017

namespace KuvaikkuWPF
{
    // -------------------------------------------
    // 3.4.2017
    // Kuvan perustiedot
    // Tässä esimerkissä tästä ei kaikkia kenttiä tarvita
    public class Kuvainfo
    {
        public int IDkoh { get; set; }   
        public string Pvmz { get; set; }
        public string Polkuz { get; set; }
        public Image Pikkukuva { get; set; }
        public double Hei { get; set; }
        public double Wid { get; set; }
    }

    // -------------------------------------------
    // 14.11.2017   S01
    // Toimintoikkunan määrittely ja kuvan käsittely
    // Tässä esimerkkikuva on tietyssä kansiossa tietyn nimisenä
    // Oikeasti polku luetaan esimerkiksi tietokannasta tai käyttäjän
    // valitsemasta kansiosta
    public partial class MainWindow : Window
    {
        public Kuvainfo kiffi;

        public MainWindow()
        {
            kiffi = new Kuvainfo();
            InitializeComponent();
            string kansioz = @"C:\Users\erkki_000\Desktop\tilap\tyo";
            string failiz = $"{kansioz}\\Orient6.JPG";
            kiffi.Polkuz = failiz;

            // tehdään esitettävän kuvan lähde
            BitmapImage bmi = new BitmapImage();
            try
            {
                bmi.BeginInit();
                bmi.UriSource = new Uri(failiz);
                // pitääkö kuvaa kiertää näytölle:
                bmi.Rotation = TarkistaAsento(failiz);

                // Työmuistin säästämiseksi lataa kuva pikkukuvana,
                // aseta joko latausleveys tai -korkeus.
                // Tässä on asetettu leveys=1400, kun paneelissa kuvan
                // leveys on noin 700.
                // MS:n dokujen mukaan arvoksi pitäisi ottaa se mikä
                // halutaan lopulliselle kuvalle. Kokeilin, että ei toimi niin,
                // vaan tässä vaiheessa otettava suurempi, ja xaml-rivi
                // hoitaa pienennyksen oikeaksi
                // Ei toimi Stretch="None" odotetusti, mikä kuulemma
                // johtuu kuvan metatietojen DPI-arvosta,
                // näyttölaitteissa yleisin on 96.
                bmi.DecodePixelWidth = 1400;
                bmi.CacheOption = BitmapCacheOption.OnLoad;
                bmi.EndInit();
                kiffi.Hei = bmi.PixelHeight;
                kiffi.Wid = bmi.PixelWidth;
            }
            catch
            {
                MessageBox.Show($"Ei kelpaa: {failiz}", "(S01-03) Ilmoitus");
                this.Close();
                return;
            }

            // näytetään kuva kohtuullisen kokoisena
            // 'esikuva' on kuvan nimi xaml:ssä
            double skrh = 600;
            double skrw = 1000;
            esikuva.Width = (skrw < kiffi.Wid) ? skrw : kiffi.Wid;
            esikuva.Height = (skrh < kiffi.Hei) ? skrh : kiffi.Hei;
            esikuva.Source = bmi;
        }

        // -------------------------------------------
        // 3.4.2017    S02
        // Näytetään kuva alkuperäisen kokoisena
        private void ButtonAlku_Click(object sender, MouseButtonEventArgs e)
        {
            esikuva.Width = kiffi.Wid;
            esikuva.Height = kiffi.Hei;
        }

        // -------------------------------------------
        // 3.4.2017   S03
        // Näytetään kuva sen kokoisena mikä sopii ikkunaan
        private void ButtonSovi_Click(object sender, MouseButtonEventArgs e)
        {
            double skrh = Skrolli.ActualHeight - 20;
            double skrw = Skrolli.ActualWidth - 20;
            esikuva.Width = (skrw < kiffi.Wid) ? skrw : kiffi.Wid;
            esikuva.Height = (skrh < kiffi.Hei) ? skrh : kiffi.Hei;
        }

        //------------------------------------------------------------
        // 11.11.2017   S04
        // Tarkista jpg-kuvan tiedoista pitääkö kuvaa kääntää
        // Muilla tiedostopäätteillä palauttaa että ei kiertämistä
        // Tuloksena tarvittava kiertäminen, esimerkiksi Rotation.Rotate270
        private Rotation TarkistaAsento(string kokopolkuz)
        {
            // tiedostopääte jonka edessä on piste:
            string extz = System.IO.Path.GetExtension(kokopolkuz);
            // pelkkä pääte pikkukirjaimilla:
            string paaz = extz.Substring(1).ToLower();
            if (!String.Equals(paaz, "jpg") && !String.Equals(paaz, "jpeg"))
                return Rotation.Rotate0;

            try
            {
                var decoder = new JpegBitmapDecoder(new Uri(kokopolkuz),
                    BitmapCreateOptions.None, BitmapCacheOption.Default);
                var metadata = (BitmapMetadata)decoder.Frames[0].Metadata;
                // exif-tietojen paikka:
                string koodiz = "/app1/ifd/{ushort=274}"
                string orientz = metadata.GetQuery(koodiz).ToString();
                if (orientz == "6")
                    return Rotation.Rotate90;
                else if (orientz == "3")
                    return Rotation.Rotate180;
                else if (orientz == "8")
                    return Rotation.Rotate270;
            }
            catch
            {
            }
            return Rotation.Rotate0;
        }
    }
}




--------------------------------
(sivua muokattu  2.2.2018)