Forum: PC-Programmierung c# Probleme beim Rotieren eines Bildes bei DrawImage


von hase (Gast)


Angehängte Dateien:

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

von hase (Gast)


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.

von Dirk K. (merciless)


Lesenswert?

Kannst du mal den ganzen Code-Ausschnitt posten,
so dass man sehen kann, was baseHeight und baseWidth
zugewiesen wird?

merciless

von Horst (Gast)


Lesenswert?

hase schrieb:
> ich versuche in c# 2 Bilder zusammenzufügen

??

Das ist etwa so dämlich wie:

"Ich versuche mit einem Klebestreifen 2 Bilder zusammenzufügen."

von c-hater (Gast)


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...

von c.m. (Gast)


Lesenswert?

was passiert denn wenn du beim rotieren nicht den mittelpunkt angibst 
(resp 0/0)?

von hase (Gast)


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

von hase (Gast)


Lesenswert?

@c.m.
dann wird das Bild aus dem Rand gedreht (weil es an der oberen Linken 
ecke angefasst wurde) <- hier wird es in der Tat perfekt getroffen.

von c-hater (Gast)


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...

von sid (Gast)


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 ;)

von c-hater (Gast)


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...

von Frank S. (schroederde)


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;

von hase (Gast)


Lesenswert?

dankschön <3

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.