2013-03-26 21 views
5

Piszę aplikację, która wymaga podziału dużego obrazu na małe płytki, gdzie każdy kafelek jest zasadniczo przyciętą wersją oryginalnego obrazu.przycinanie obrazu bez kopiowania

Obecnie mój rozłam operacja wygląda tak

tile.Image = new BitmapImage(); 
tile.Image.BeginInit(); 
tile.Image.UriSource = OriginalImage.UriSource; 
tile.Image.SourceRect = new Int32Rect(x * tileWidth + x, y * tileHeight, tileWidth, tileHeight); 
tile.Image.EndInit(); 

Intuicyjnie, myślałem, że spowodowałoby to w zasadzie „odniesienie” do oryginalnego obrazu, a po prostu wyświetlać jako prostokąt sub obrazu. Jednak powolna prędkość, z jaką wykonuje się moja dzielona operacja, doprowadziła mnie do przekonania, że ​​w rzeczywistości jest to kopiowanie źródła prostego obrazu oryginalnego, który jest bardzo powolny dla dużych obrazów (zauważalne jest 3-4-sekundowe pauzowanie podczas dzielenia przyzwoitego rozmiar obrazu).

Rozejrzałem się trochę, ale nie byłem w stanie znaleźć sposobu na zrobienie mapy bitowej jako podrzutu dużego obrazu, bez kopiowania żadnych danych. Jakieś sugestie?

+0

próbowałeś tworzyć nowe 'Bitmap' i blittingiem do niego? Myślę, że może to być szybsze niż próba przycięcia obrazu w linii. –

+0

Twoja klasa 'tile' może przechowywać odniesienie do oryginalnego obrazu i prostokąta do skopiowania podczas rysowania? Graphics.DrawImage ma przeciążenia, aby narysować część bitmapy: http://msdn.microsoft.com/en-us/library/3tf158xz.aspx – Blorgbeard

+0

Nie jestem wprawdzie ekspertem od manipulacji obrazem, ale nie jestem pewien to, o co prosisz, ma sens. Chociaż może istnieć mechanizm ukrywania kopii, podejrzewam, że dane obrazu muszą być "wyrównywane" (kopiowane) w pamięci w dowolny sposób. – svidgen

Odpowiedz

4

Użyj klasę System.Windows.Media.Imaging.CroppedBitmap:

// Create a CroppedBitmap from the original image. 
Int32Rect rect = new Int32Rect(x * tileWidth + x, y * tileHeight, tileWidth, tileHeight); 
CroppedBitmap croppedBitmap = new CroppedBitmap(originalImage, rect); 

// Create an Image element. 
Image tileImage = new Image(); 
tileImage.Width = tileWidth; 
tileImage.Height = tileHeight; 
tileImage.Source = croppedBitmap; 
+1

Wcześniej zauważyłem, że nie zwiększyło to wydajności tak bardzo, ale po prostu spróbowałem starej drogi ponownie, co w rzeczywistości daje znaczący wzrost wydajności (z blisko 6 sekund dla podziału na więcej niż 1 sekundę). – phosphoer

Powiązane problemy