c# Probleme beim Rotieren eines Bildes bei DrawImage

Gast #6093062
Lesenswert?

Hi,

ich versuche in c# 2 Bilder zusammenzufügen (Wasserzeichen). 
Gleichzeitig habe ich aber das Problem dass ich manche Bilder drehen 
muss (andere nicht).

Zuerst lade ich mit die BitmapFrame´s und füge dann im DrawinContext die 
Beiden Frames ein.

Soll ein Bild gedreht werden, schreibe ich ein PushTransform davor, 
welches dann die 90° anwendet. Hier mal der Code für ein Bild:
1
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
2
{
3
  //wenn rotiert wird
4
  drawingContext.PushTransform(new RotateTransform(90, baseHeight / 2, baseWidth / 2));
5
  drawingContext.DrawImage(baseimage, new Rect(0, 0, baseWidth, baseHeight));
6
}
7

8
//wenn rotiert wird
9
int tmp = baseWidth;
10
baseWidth = baseHeight;
11
baseHeight = tmp;
12

13
RenderTargetBitmap bmp = new RenderTargetBitmap(baseWidth, baseHeight, dpi, dpi, PixelFormats.Pbgra32);

leider habe ich das Problem, dass mein Bild bei der Ausgabe nicht mittig 
sitzt. Ich habe Oben und Links einen schwarzen Rand.

=> Wenn ich das Bild nicht rotiere, passt es perfekt

welchen Denkfehler habe ich?
=> wenn ich das Bild auf exakt 1/4 der Breite verschiebe (negativ von 
links, positiv von oben) ansetze, passt das Bild... das ergibt aber für 
mich keinen Sinn <- woher kommt die Verschiebung?

> Im Anhang ein kleiner Export

VIelen Dank
Angehängte Dateien:
Gast #6093066
Lesenswert?

kleiner Nachtrag:
1
drawingContext.PushTransform(new RotateTransform(90, baseHeight / 2, baseWidth / 2));

oder
1
drawingContext.PushTransform(new RotateTransform(90, baseWidth / 2, baseHeight / 2));

verschiebt lediglich das Bild nach oben oder unten, kommt aber nicht der 
gewollten Drehung näher.
Gast #6093636
Lesenswert?

hase schrieb:

> leider habe ich das Problem, dass mein Bild bei der Ausgabe nicht mittig
> sitzt. Ich habe Oben und Links einen schwarzen Rand.
>
> => Wenn ich das Bild nicht rotiere, passt es perfekt
>
> welchen Denkfehler habe ich?

Du hast nicht darüber nachgedacht, wo wohl das Zentrum der Rotation 
liegen mag...
Gast #6093645
Lesenswert?

@c-hater

> Du hast nicht darüber nachgedacht, wo wohl das Zentrum der Rotation
> liegen mag...

doch sogar sehr lange... <- aber bestimmt nicht richtig :D

> new RotateTransform(90, baseHeight / 2, baseWidth / 2);

Leider bringt mich das nicht weiter. Ich dachte immer, die halbe Höhe 
und die halbe Breite meiner "Bildgröße" (oder auch die Größe einer 
Fläche) müsste der Mittelpunkt sein.

@Dirk
Es ist völlig egal, ob ich hierfür ein Bild oder ein Rechteck nehme...
1
drawingContext.DrawImage(baseimage, new Rect(0, 0, baseWidth, baseHeight));

und auch baseWidth und baseHeight ist per definition egal. Wenn ich hier 
festwerte (z.B. 1000 & 2000) angebe und später in das Bild schreibe mit.
1
RenderTargetBitmap bmp = new RenderTargetBitmap(baseWidth, baseHeight, dpi, dpi, PixelFormats.Pbgra32);

ist das ganze "verschoben".

@Horst
> Wertvolle Beiträge auf dem Niveau, kennt man sonst nur von Trump auf
> Twitter...
> Selbst wenn du C# offenkundig nicht magst, kennst du doch nicht die
> Gegebenheiten, warum ich das tue???

Cheers
Gast #6093751
Lesenswert?

hase schrieb:

> doch sogar sehr lange... <- aber bestimmt nicht richtig :D

Das ist ja nun offensichtlich...

Ob die ein echter Programmierer bist, zeigt sich in genau solchen 
Situationen. Die erste Idee war offensichtlich falsch. Was mache ich 
nun?

Tipp: Doku lesen schadet definitiv nicht. Auch wenn sie im konkreten 
Fall nicht gerade sehr schick ist und im ersten Anlauf einigermaßen 
un/miß-verständlich. Sie liefert aber Stoff für weitere Hypothesen, die 
man dann mit der Praxis abgleichen kann...

Nach einem Nachmittag zielgerichtetem Probierens hat man das Problem so 
weit im Griff, dass man das KONZEPT der Transformationen verstanden 
hat und es dann auch bei komplexeren Sachen als bei deinem primitiven 
Problem korrekt verwenden kann...

Und dann erschließt sich auch der Sinn der Formulierungen in der Doku...
Gast #6093817
Lesenswert?

Also ehrlich,

wenn man die Antwort nicht kennt, den Fragenden anzublöken er soll halt 
mehr lernen ist doch auch Käse!

Ich kenne die Antwort auch nicht,
weiss aber, daß viele rotate implementationen schlicht und ergreifend um 
origin rotieren.

Also wär mein nächster Ansatz den Origin zu verschieben
(TranslateTransform((float)width/2, (float)height/2))
danach rotieren (RotateTransform(90)) und dann wieder zurückzuschieben 
(TranslateTransform(-(float)width/2, -(float)height/2))
und ja ich habe absichtlich keine code tags gesetzt, weil das vollends 
aus den Fingern gesogener Versuchsaufbau wäre,

Ich glaube übrigens, dass Du eventuell keine "zwischengespeicherten 
Werte"
nutzen kannst beim zweiten Translate, da sich width und height 
vertauscht haben könnten (naja oder Du musst halt auch tauschen)

Aber wie gesagt, ich weiss es nicht wirklich, ich rate nur mit quasi ;)
Gast #6094913
Lesenswert?

sid schrieb:

> weiss aber, daß viele rotate implementationen schlicht und ergreifend um
> origin rotieren.

Das tun sogar ausnahmlos alle. Denn: eine Rotation muss nunmal um 
irgendeinen Punkt herum passieren, sonst kann es keine Rotation sein...

Das Problem ist der Bezug von "origin". Also: In welchem 
Koordinatensystem ist dieser Punkt anzugeben...
#6096373
Lesenswert?

Wo ist der allwissende Marvin?

Quick and Dirty. Alles was Du brauchst:

      BitmapImage sourceImage;
            if (filename == null)
                return;

            sourceImage = new BitmapImage(new Uri(filename));

            var dpiXProperty = 
typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | 
BindingFlags.Static);
            var dpiYProperty = 
typeof(SystemParameters).GetProperty("Dpi", BindingFlags.NonPublic | 
BindingFlags.Static);

            var dpiX = (int)dpiXProperty.GetValue(null, null);
            var dpiY = (int)dpiYProperty.GetValue(null, null);




            double sourceImageDpiX = sourceImage.DpiX;
            double sourceImageDpiY = sourceImage.DpiY;

            double centerX = sourceImage.PixelWidth / 2.0 / 
sourceImageDpiX * dpiX;
            double centerY = sourceImage.PixelHeight / 2.0 / 
sourceImageDpiY * dpiY;

            RotateTransform rotateTransform = new RotateTransform();
            rotateTransform.CenterX = centerX;
            rotateTransform.CenterY = centerY;
            rotateTransform.Angle   = SliderRotation.Value;

            double targetWidthInScreenUnits  = sourceImage.Width / 
sourceImageDpiX * dpiX;
            double targetHeightInScreenUnits = sourceImage.Height / 
sourceImageDpiY * dpiY;

            TranslateTransform translateTransform = new 
TranslateTransform();
            translateTransform.X = -1 * (centerX - 
targetWidthInScreenUnits / 2);
            translateTransform.Y = -1 * (centerY - 
targetHeightInScreenUnits / 2);

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(rotateTransform);
            transformGroup.Children.Add(translateTransform);

            Image image = new Image();
            image.Stretch = Stretch.None;
            image.Source = sourceImage;
            image.RenderTransform = transformGroup;

            Canvas canvas = new Canvas();
            canvas.Background = Brushes.Lavender;
            canvas.Children.Add(image);
            canvas.Arrange(new 
Rect(0,0,sourceImage.PixelWidth,sourceImage.PixelHeight));

            RenderTargetBitmap zielBitmap = new 
RenderTargetBitmap((int)sourceImage.Width,(int)sourceImage.Height,source 
Image.DpiX,sourceImage.DpiY,PixelFormats.Default);
            zielBitmap.Render(canvas);
            ImageZiel.Source = null;
            ImageZiel.Source = zielBitmap;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren