Benutzer mit den meisten Antworten
WPF - UriSource eines Objektes

Frage
-
Hallo,
ich habe ein RenderTargetBitmap als Objekt hinterlegt. Nun möchte ich dazu ein Vorschaubild generieren (also mit kleinerer Auflösung), ohne dabei über eine temporäre Datei zu gehen. Wie kann ich ein Objekt als UriSource angeben? Das ganze sollte möglichst schnell sein, daher arbeite ich hier nur ungern mit temporären Dateien. Mein Code (mit ungültigen UriSource Parameter):
RenderTargetBitmap cacheSaveImg = new RenderTargetBitmap(); //Ein Bild anlegen //... //Vorschaubild generieren BitmapImage bmpImg = new BitmapImage(); bmpImg.BeginInit(); bmpImg.CacheOption = BitmapCacheOption.OnLoad; bmpImg.DecodePixelHeight = 240; bmpImg.UriSource = cacheSaveImg; bmpImg.EndInit(); bmpImg.Freeze();
Antworten
-
Hi User,
Du kannst über ein Byte-Array Dein Ansinnen ausführen, ohne auf Dateien zurückzugreifen. Hier mal eine kleine Demo:XAML:
<Window x:Class="WpfApp1CS.Window35" 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:WpfApp1CS" mc:Ignorable="d" Title="Window35" Height="300" Width="300"> <Window.Resources> <local:Window35VM x:Key="vm"/> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border Grid.Column="0" BorderBrush="Green" BorderThickness="2" Margin="5"> <Image Source="{Binding Bild1}"/> </Border> <Border Grid.Column="1" BorderBrush="DarkSalmon" BorderThickness="2" Margin="5"> <Image Source="{Binding Bild2}"/> </Border> </Grid> </Window>
ViewModel dazu:
using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfApp1CS { public class Window35VM { public RenderTargetBitmap Bild1 { get { return GetBitmap(); } } public RenderTargetBitmap Bild2 { get { // neue Größe int newWidth = 100; int newHeight = 100; // Schritt 1: Pixel-Array erzeugen und füllen RenderTargetBitmap bmp1 = GetBitmap(); int stride1 = newWidth * (bmp1.Format.BitsPerPixel + 7) / 8; byte[] data = new byte[stride1 * bmp1.PixelHeight]; bmp1.CopyPixels(new Int32Rect(0, 0, newWidth, newHeight), data, stride1, 0); // Schritt 2: aus Pixel-Array neue ImageSource erzeugen PixelFormat pf = PixelFormats.Bgr32; int stride2 = newWidth * (pf.BitsPerPixel + 7) / 8; ImageSource bmps = BitmapSource.Create(newWidth, newHeight, 96, 96, pf, null, data, stride2); // Schritt 3: aus ImageSource neues RenderTargetBitmap erzeuegn und füllen RenderTargetBitmap bmp2 = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32); DrawingVisual dv = new DrawingVisual(); DrawingContext dctx = dv.RenderOpen(); dctx.DrawImage(bmps, new Rect(0, 0, 100, 100)); dctx.Close(); bmp2.Render(dv); return bmp2; } } RenderTargetBitmap bmp; private RenderTargetBitmap GetBitmap() { if (bmp == null) { FormattedText txt = new FormattedText("Demo", new CultureInfo("de-de"), FlowDirection.LeftToRight, new Typeface(new FontFamily(), FontStyles.Normal, FontWeights.Normal, new FontStretch()), 20, Brushes.Red); DrawingVisual dv = new DrawingVisual(); DrawingContext dctx = dv.RenderOpen(); dctx.DrawRectangle(Brushes.Yellow, new Pen(Brushes.Blue, 4), new Rect(2, 2, 196, 196)); dctx.DrawText(txt, new Point(10, 10)); dctx.Close(); bmp = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32); bmp.Render(dv); } return bmp; } } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 26. Februar 2018 08:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 7. März 2018 13:39
Alle Antworten
-
Leider wird dort der Umweg über eine Datei gemacht. Also eine Datei wird zwei mal mit unterschiedlichen Auflösungen geladen. Meine Frage war, ob man nicht direkt das Bild aus dem RAM (in meinem Fall cacheSaveImg) nehmen kann, um eine Vorschau zu erstellen.
-
Hallo,
Du kannst das mit einer Bitmap oder mit Graphics machen. Schau mal hier link. Ich bevorzuge meist die Bitmap da sie handlicher ist und es stehen alle Möglichkeiten offen
Gruß Thomas
Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!
Dev Apps von mir: Icon für UWP, UI Strings
Andere Dev Apps: UWP Community Toolkit Sample App- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 26. Februar 2018 08:21
-
Hi User,
Du kannst über ein Byte-Array Dein Ansinnen ausführen, ohne auf Dateien zurückzugreifen. Hier mal eine kleine Demo:XAML:
<Window x:Class="WpfApp1CS.Window35" 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:WpfApp1CS" mc:Ignorable="d" Title="Window35" Height="300" Width="300"> <Window.Resources> <local:Window35VM x:Key="vm"/> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border Grid.Column="0" BorderBrush="Green" BorderThickness="2" Margin="5"> <Image Source="{Binding Bild1}"/> </Border> <Border Grid.Column="1" BorderBrush="DarkSalmon" BorderThickness="2" Margin="5"> <Image Source="{Binding Bild2}"/> </Border> </Grid> </Window>
ViewModel dazu:
using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfApp1CS { public class Window35VM { public RenderTargetBitmap Bild1 { get { return GetBitmap(); } } public RenderTargetBitmap Bild2 { get { // neue Größe int newWidth = 100; int newHeight = 100; // Schritt 1: Pixel-Array erzeugen und füllen RenderTargetBitmap bmp1 = GetBitmap(); int stride1 = newWidth * (bmp1.Format.BitsPerPixel + 7) / 8; byte[] data = new byte[stride1 * bmp1.PixelHeight]; bmp1.CopyPixels(new Int32Rect(0, 0, newWidth, newHeight), data, stride1, 0); // Schritt 2: aus Pixel-Array neue ImageSource erzeugen PixelFormat pf = PixelFormats.Bgr32; int stride2 = newWidth * (pf.BitsPerPixel + 7) / 8; ImageSource bmps = BitmapSource.Create(newWidth, newHeight, 96, 96, pf, null, data, stride2); // Schritt 3: aus ImageSource neues RenderTargetBitmap erzeuegn und füllen RenderTargetBitmap bmp2 = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32); DrawingVisual dv = new DrawingVisual(); DrawingContext dctx = dv.RenderOpen(); dctx.DrawImage(bmps, new Rect(0, 0, 100, 100)); dctx.Close(); bmp2.Render(dv); return bmp2; } } RenderTargetBitmap bmp; private RenderTargetBitmap GetBitmap() { if (bmp == null) { FormattedText txt = new FormattedText("Demo", new CultureInfo("de-de"), FlowDirection.LeftToRight, new Typeface(new FontFamily(), FontStyles.Normal, FontWeights.Normal, new FontStretch()), 20, Brushes.Red); DrawingVisual dv = new DrawingVisual(); DrawingContext dctx = dv.RenderOpen(); dctx.DrawRectangle(Brushes.Yellow, new Pen(Brushes.Blue, 4), new Rect(2, 2, 196, 196)); dctx.DrawText(txt, new Point(10, 10)); dctx.Close(); bmp = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32); bmp.Render(dv); } return bmp; } } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 26. Februar 2018 08:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 7. März 2018 13:39