2009-08-17 14 views
1

Ich muss ein Bild drehen, das an eine Funktion als ein Array von BitmapFrames übergeben wird. Das fertige Produkt muss auch als BitmapFrame gespeichert werden, damit ich es an meine Export-Image-Funktion senden kann. Hilfe?Ich muss ein Bild drehen

[Cmdlet(VerbsData.ConvertTo, "Rotate")] 
public class RotateCmdlet : PSCmdlet 
{ 
    private BitmapFrame[] bFrame, outFrame; 
    private BitmapSource src; 
    private double pixelsize; 
    private int degrees; 
    private byte[] pixels, outPixels; 

    [Parameter(ValueFromPipeline = true, 
     ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] 
    public BitmapFrame[] Bitmap 
    { 
     get 
     { 
      return bFrame; 
     } 
     set 
     { 
      bFrame = value; 
     } 
    } 

    [Parameter(Position = 0), ValidateNotNullOrEmpty] 
    public int Degrees 
    { 
     get 
     { 
      return degrees; 
     } 
     set 
     { 
      degrees = value; 
     } 
    } 

    protected override void ProcessRecord() 
    { 
     base.ProcessRecord(); 
     Console.Write("Rotating the image {0} degrees...\n\n", degrees); 
     outFrame = new BitmapFrame[bFrame.Length]; 
     for (int c = 0; c < bFrame.Length; c++) 
     { 
      Image image; 

      pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight; 
      pixels = new byte[(int)pixelsize]; 
      outPixels = new byte[(int)pixelsize]; 
      bFrame[c].CopyPixels(pixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel/8.0)), 0); 

      Stream strm = new MemoryStream(pixels); 
      image = Image.FromStream(strm); 

      var newBitmap = new Bitmap((int)bFrame[c].PixelWidth, (int)bFrame[c].PixelHeight); 
      var graphics = Graphics.FromImage(newBitmap); 
      graphics.TranslateTransform((float)bFrame[c].PixelWidth/2, (float)bFrame[c].PixelHeight/2); 
      graphics.RotateTransform(degrees); 
      graphics.TranslateTransform(-(float)bFrame[c].PixelWidth/2, -(float)bFrame[c].PixelHeight/2); 
      graphics.DrawImage(image, new System.Drawing.Point(0, 0)); 

      for (int i = 0; i < pixelsize; i++) 
      { 
       outPixels[i] = pixels[i]; 
      } 

      src = BitmapSource.Create(bFrame[c].PixelWidth, bFrame[c].PixelHeight, bFrame[c].DpiX, bFrame[c].DpiY, 
       bFrame[c].Format, bFrame[c].Palette, outPixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel/8))); 
      outFrame[c] = BitmapFrame.Create(src); 
     } 
     WriteObject(outFrame); 
    } 
} 
+0

Ein bisschen mehr Info wäre schön :) Was ist los mit dem Code, den Sie gebucht haben, zum Beispiel? – cwap

+0

Auch (nicht relevant für Ihre Frage) Sie möchten Dispose() für alle Sachen, die Sie hier verwenden, wie Stream, Bitmap und Grafiken (oder verwenden Sie sie in einem using() -Block). – MusiGenesis

+0

Sie können möglicherweise weitere Informationen über das Problem von dabonz413 hier herleiten: http://www.stackoverflow.com/questions/1190743/ Ich hatte noch keine Zeit, den Code gründlich durchzugehen, und ich habe diese Frage ein paar Wochen gestellt Vor, also bin ich nicht ganz frisch darauf. Aber ich werde hier wieder posten, wenn ich am Ende noch nützlichere (oder kontextbezogene) Informationen finde. – Giffyguy

Antwort

1

Es scheint, dass der Fehler, den Sie auf den FromStream-Aufruf erhalten, möglicherweise daran liegt, dass das Bildformat ungültig ist. Dies kann viele Gründe haben und da ich mir nicht sicher bin, wie genau dieses Cmdlet verwendet wird, werde ich eine Annahme machen:

Ich mag hier falsch sein, aber da Sie ein Array von BitMapFrames übergeben, ich ' Ich frage mich, ob die ProcessRecord einmal für jedes Array-Element aufgerufen wird. Der einzige Weg, um wirklich zu erzählen, ist zu sehen, wie Sie Cmdlet aufgerufen wird. Wenn beispielsweise Ihr BitMap-Parameter aus der Pipeline kommt, besteht eine gute Chance, dass ProcessRecord für jeden BitMapFrame im Array einmal aufgerufen wird.

Macht das Sinn?

+0

dies der Befehl ist, den ich in die Eingabeaufforderung dafür stecke: Import-Image E: \ RawConvert \ lenna.arf | ConvertTo-Rotate 90 | Export-Image E: \ RawConvert \ rotate.jpg Es erhält alle Frames in ein Array im Import, sendet an das Dreh-Cmdlet (mit 90 Grad) mit den Frames durch Pipeline gesendet wird. aber ich dachte, da die einzige Schleife innerhalb des ProcessRecord war, würde sie es nur einmal nennen? Was ist falsch an meinem Bildformat? – dabonz413

+0

Ich war nur neugierig, wie das Cmdlet aufgerufen wird, denn wenn es Teil der Pipeline ist und foreach-Objekt auch verwendet wird, dann wird ProcessRecord jedes Mal aufgerufen. Wenn dies der Fall wäre, wäre das Bildformat falsch und es würde dazu führen, dass FromStream fehlschlägt (d. H. Es hat nur einen Teil des BitMapFrame). –

+0

Nur um sicherzustellen, können Sie überprüfen, ob Ihr ConvertTo-Rotate90 Cmdlet NUR einmal aufgerufen wird, wenn Sie den Befehl wie oben angegeben ausführen? Es scheint, dass es sehr wahrscheinlich ist, dass es für jedes Element in dem Array, das das Import-Image an es übergibt, einmal aufgerufen wird. –