2011-01-13 15 views
5

Si tratta di un follow-up domanda su Save image to file keeping aspect ration in a WPF appEspandi tela/sfondo trasparente in BitmapImage in un'applicazione WPF

So scala howto l'immagine, ma come faccio a espandere le dimensioni della tela, al fine di garantire il fermo immagine è la richiesta larghezza e altezza. In questo esempio la sua 250x250 ma la sua dinamica.

Ho creato questa illustrazione per mostrare quello che sto cercando di complice. alt text

non riesco a trovare alcun modo di espandere la tela di un BitmapImage, né un modo per creare un'immagine memoria nel formato corretto, con uno sfondo trasparente, e quindi unendo le due immagini.

risposta

6

CroppedBitmap non sembra supportare l'aggiunta di spazio attorno a un'immagine, quindi è possibile creare un'immagine trasparente della dimensione corretta utilizzando WriteableBitmap. Se l'input è inferiore alla dimensione target, questo metodo lo ingrandirà, ma è facile modificarlo.

public static BitmapSource FitImage(BitmapSource input, int width, int height) 
{ 
    if (input.PixelWidth == width && input.PixelHeight == height) 
     return input; 

    if(input.Format != PixelFormats.Bgra32 || input.Format != PixelFormats.Pbgra32) 
     input = new FormatConvertedBitmap(input, PixelFormats.Bgra32, null, 0); 

    //Use the same scale for x and y to keep aspect ratio. 
    double scale = Math.Min((double)width/input.PixelWidth, height/(double)input.PixelHeight); 

    int x = (int)Math.Round((width - (input.PixelWidth * scale))/2); 
    int y = (int)Math.Round((height - (input.PixelHeight * scale))/2); 


    var scaled = new TransformedBitmap(input, new ScaleTransform(scale, scale)); 
    var stride = scaled.PixelWidth * (scaled.Format.BitsPerPixel/8); 

    var result = new WriteableBitmap(width, height, input.DpiX, input.DpiY, input.Format,null); 

    var data = new byte[scaled.PixelHeight * stride]; 
    scaled.CopyPixels(data, stride, 0); 
    result.WritePixels(new Int32Rect(0,0,scaled.PixelWidth,scaled.PixelHeight), data, stride,x,y); 
    return result; 
} 

Se sei già il rendering di contenuti utilizzando RenderTargetBitmap si poteva avvolgerlo in un viewBox per fare la scala, ma se si sta solo lavorando con immagini normali userei il metodo di cui sopra.

+0

@Kris Sembra molto promettente. Sono nuovo di questi metodi. Puoi dirmi la differenza tra BitmapSource e BitmapFrame? Sto usando BitmapFrame per ridimensionare la mia immagine. – mrtsherman

+0

@Kris Okay, vedo che BitmapFrame è figlio di BitmapSource. Quindi dovrebbe essere in grado di adattare il codice al lavoro. Provando me stesso adesso. – mrtsherman

+0

L'uso principale di BitmapFrame è dato dal fatto che alcuni formati di immagine come gif possono avere più fotogrammi, inoltre li lega a un decodificatore e fornisce una miniatura, per una spiegazione migliore vedi http://stackoverflow.com/questions/155391/difference-training- a-bitmapframe-and-bitmapimage-in-wpf – Kris

0

Dovresti essere in grado di impostare la proprietà Stretch su Uniforme.

+0

Ma questo non funzionerà, quando salverò l'immagine. – gulbaek

+0

Che ne dici di salvare l'immagine dalla tela su cui è attiva? –

+0

Qualche possibilità di creare un piccolo esempio per illustrare questo? Come possiamo, nella mia domanda precedente, non sto usando una tela, ma carica l'immagine in una BitmapImage e poi la carica in una TransformedBitmap per ridimensionarla, ma non dare la giusta dimensione di output. – gulbaek

0

Solo un po 'di codice nel caso in cui altri stiano provando a postare file da un caricamento del modulo.

if (file.PostedFile != null) 
{ 
    //write the new file to disk 
    string cachePath = String.Format("{0}temp\\", Request.PhysicalApplicationPath); 
    string photoPath = String.Format("{0}temp.png", cachePath);     
    if (!Directory.Exists(cachePath)) 
{ 
    Directory.CreateDirectory(cachePath); 
}  

file.PostedFile.SaveAs(photoPath); 

//resize the new file and save it to disk    
BitmapSource banana = FitImage(ReadBitmapFrame(file.PostedFile.InputStream), 640, 480); 
PngBitmapEncoder encoder = new PngBitmapEncoder(); 
encoder.Frames.Add(BitmapFrame.Create(banana)); 
FileStream pngStream = new FileStream(cachePath + "test.png", FileMode.Create); 
encoder.Save(pngStream); 
pngStream.Close(); 

//set a couple images on page to the newly uploaded and newly processed files 
image.Src = "temp/temp.png"; 
image.Visible = true; 
image2.Src = "temp/test.png"; 


    image2.Visible = true; 
} 
Problemi correlati