public MainWindow() { InitializeComponent(); var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image.png"); var frame = BitmapFrame.Create(new Uri(path)); var crop = new CroppedBitmap(); crop.BeginInit(); crop.Source = frame; crop.SourceRect = new Int32Rect(100, 150, 400, 250); crop.EndInit(); var color = new FormatConvertedBitmap(); color.BeginInit(); color.Source = crop; color.DestinationFormat = PixelFormats.BlackWhite; color.EndInit(); var image = new Image(); image.Source = color; Content = image; Title = "画像パイプライン"; DumpMetadata(frame.Metadata); }
public CroppedBitmapExample() { ///// Create a BitmapImage and set it's DecodePixelWidth to 200. Use ///// ///// this BitmapImage as a source for other BitmapSource objects. ///// BitmapImage myBitmapImage = new BitmapImage(); // BitmapSource objects like BitmapImage can only have their properties // changed within a BeginInit/EndInit block. myBitmapImage.BeginInit(); myBitmapImage.UriSource = new Uri(@"sampleImages/WaterLilies.jpg", UriKind.Relative); // To save significant application memory, set the DecodePixelWidth or // DecodePixelHeight of the BitmapImage value of the image source to the desired // height or width of the rendered image. If you don't do this, the application will // cache the image as though it were rendered as its normal size rather then just // the size that is displayed. // Note: In order to preserve aspect ratio, set DecodePixelWidth // or DecodePixelHeight but not both. myBitmapImage.DecodePixelWidth = 200; myBitmapImage.EndInit(); ////////// Crop the BitmapSource //////////// // Use the BitmapImage created above as the source for a new BitmapSource object // which is cropped. // Note: New BitmapSource does not cache. It is always pulled when required. CroppedBitmap myCroppedBitmap = new CroppedBitmap(); // BitmapSource objects like CroppedBitmap can only have their properties // changed within a BeginInit/EndInit block. myCroppedBitmap.BeginInit(); // Use the BitmapSource object defined above as the source for this new // BitmapSource (chain the BitmapSource objects together). myCroppedBitmap.Source = myBitmapImage; // Crop the image to the rectangular area defined below. // The image is cropped to 80 pixels less in width and 60 less // in height then the original source. myCroppedBitmap.SourceRect = new Int32Rect(0, 0, (int)myBitmapImage.Width - 80, (int)myBitmapImage.Height - 60); myCroppedBitmap.EndInit(); // Create Image Element Image myImage = new Image(); myImage.Width = 200; //set image source myImage.Source = myCroppedBitmap; // Add Image to the UI StackPanel myStackPanel = new StackPanel(); myStackPanel.Children.Add(myImage); this.Content = myStackPanel; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { CroppedBitmap cb = new CroppedBitmap(); cb.BeginInit(); cb.Source = (BitmapSource)value; cb.SourceRect = new Int32Rect(int.Parse(parameter.ToString()), 0, 256, 256); cb.EndInit(); return(new ImageBrush((ImageSource)cb)); //return (ImageSource)cb; }
/// <summary> /// ソースの画像から指定座標が示すブロック画像を切り出しで取得します。 /// </summary> private CroppedBitmap load_single_image(BitmapImage src_img, int x, int y) { var crppped_img = new CroppedBitmap(); crppped_img.BeginInit(); crppped_img.Source = src_img; // サイズの指定 crppped_img.SourceRect = new Int32Rect(x, y, GameCondition.ImageWidth, GameCondition.ImageHight); crppped_img.EndInit(); return(crppped_img); }
private static void UpdateCornerImage(Image image, Grid imageHolder, BitmapSource bitmap, RegionChooser regionChooser, bool isRetry = false) { // Image dimensions int imageWidth = bitmap.PixelWidth; int imageHeight = bitmap.PixelHeight; double availableWidth = imageHolder.ActualWidth; double availableHeight = imageHolder.ActualHeight; if (availableWidth == 0 || availableHeight == 0) { // Intermittent bug causing this. In this case we queue it up to go again after a layout pass has been done. if (!isRetry) { DispatchUtilities.BeginInvoke(() => { UpdateCornerImage(image, imageHolder, bitmap, regionChooser, isRetry: true); }); } return; } int cornerWidthPixels = (int)(availableWidth / ZoomedPixelSize); int cornerHeightPixels = (int)(availableHeight / ZoomedPixelSize); // Make sure the subsection of the image is not larger than the image itself cornerWidthPixels = Math.Min(cornerWidthPixels, imageWidth); cornerHeightPixels = Math.Min(cornerHeightPixels, imageHeight); double cornerWidth = cornerWidthPixels * ZoomedPixelSize; double cornerHeight = cornerHeightPixels * ZoomedPixelSize; var croppedBitmap = new CroppedBitmap(); croppedBitmap.BeginInit(); croppedBitmap.SourceRect = regionChooser(imageWidth, imageHeight, cornerWidthPixels, cornerHeightPixels); croppedBitmap.Source = bitmap; croppedBitmap.EndInit(); image.Source = croppedBitmap; image.Width = cornerWidth; image.Height = cornerHeight; }
/// <summary> /// When implemented in a derived class, returns an object that is provided as the value of /// the target property for this markup extension. /// </summary> /// <param name="serviceProvider"> /// A service provider helper that can provide services for the markup extension. /// </param> /// <returns> /// The object value to set on the property where the extension is applied. /// </returns> public override object ProvideValue(IServiceProvider serviceProvider) { // Setting BitmapImage.SourceRect has no effect. Need to use CroppedBitmap. if (WindowsHelper.IsInDesignMode) { // ----- Design time: // Design mode requires special code when used inside a WPF styles. var bitmapImage = Source as BitmapImage; if (bitmapImage == null) { return(null); } var croppedBitmap = new CroppedBitmap(); croppedBitmap.BeginInit(); croppedBitmap.Source = new BitmapImage(bitmapImage.UriSource); croppedBitmap.SourceRect = SourceRect; croppedBitmap.EndInit(); croppedBitmap.Freeze(); return(croppedBitmap); } else { // ----- Run time: var bitmapSource = Source as BitmapSource; if (bitmapSource == null) { return(null); } // Freeze bitmap for performance. bitmapSource.Freeze(); var croppedBitmap = new CroppedBitmap(bitmapSource, SourceRect); croppedBitmap.Freeze(); return(croppedBitmap); } }
private void updateSlicePreview(object sender, EventArgs e) { //clear the current preview slicePreview.RowDefinitions.Clear(); slicePreview.ColumnDefinitions.Clear(); slicePreview.Children.Clear(); slicePreview.Margin = new Thickness(0); //define ouputs int iFrameWidth = 0; int iFrameHeight = 0; int iFrameCount = 0; int iAnimOffsetX = 0; int iAnimOffsetY = 0; float fWorldWidth = 0; float fWorldHeight = 0; //parse input values bool hasWidth = int.TryParse(frameWidth.Text, out iFrameWidth); bool hasHeight = int.TryParse(frameHeight.Text, out iFrameHeight); bool hasCount = int.TryParse(totalFrames.Text, out iFrameCount); bool hasOffsetX = int.TryParse(animOffsetX.Text, out iAnimOffsetX); bool hasOffsetY = int.TryParse(animOffsetY.Text, out iAnimOffsetY); bool hasWorldWidth = float.TryParse(worldWidth.Text, out fWorldWidth); bool hasWorldHeight = float.TryParse(worldHeight.Text, out fWorldHeight); //reset error states for inputs frameWidth.Background = new SolidColorBrush(Colors.White); frameHeight.Background = new SolidColorBrush(Colors.White); //minimum fields required to create preview if (hasWidth && hasHeight && hasCount && sourceTexture != null && iFrameWidth > 0 && iFrameHeight > 0) { //the number of rows and colums that the frames will comprise int columns = sourceTexture.PixelWidth / iFrameWidth; int rows = sourceTexture.PixelHeight / iFrameHeight; //the dimensions of the frames for the preview image int columnWidth = (int)(((float)iFrameWidth / (float)sourceTexture.PixelWidth) * Texture.ActualWidth); int rowHeight = (int)(((float)iFrameHeight / (float)sourceTexture.PixelHeight) * Texture.ActualHeight); //prevent invalid preview if (rows > 0 && columns > 0) { //create the column definitions for (int i = 0; i < columns; i++) { ColumnDefinition newCol = new ColumnDefinition(); newCol.Width = new GridLength(columnWidth); slicePreview.ColumnDefinitions.Add(newCol); } //create row definitions for (int i = 0; i < rows; i++) { RowDefinition newRow = new RowDefinition(); newRow.Height = new GridLength(rowHeight); slicePreview.RowDefinitions.Add(newRow); } //create the rectangles (frames) that overlay the texture for (int i = 0; i < iFrameCount; i++) { Border newDiv = new Border(); newDiv.BorderThickness = new Thickness(1); newDiv.BorderBrush = new SolidColorBrush(Colors.Black); newDiv.SetValue(Grid.RowProperty, (int)(i / columns)); newDiv.SetValue(Grid.ColumnProperty, (int)(i % columns)); slicePreview.Children.Add(newDiv); } //the animation offset from the top-left of the spritesheet int iRelOffsetX = (int)(Texture.ActualWidth * ((float)iAnimOffsetX / (float)sourceTexture.PixelWidth)); int iRelOffsetY = (int)(Texture.ActualHeight * ((float)iAnimOffsetY / (float)sourceTexture.PixelHeight)); slicePreview.Margin = new Thickness(iRelOffsetX, iRelOffsetY, 0, 0); //check if we have enough information to create a preview of the object in the game world if (hasWorldWidth && hasWorldHeight && iAnimOffsetX + iFrameWidth <= sourceTexture.PixelWidth && iAnimOffsetY + iFrameHeight <= sourceTexture.PixelHeight) { //pull the first frame to use for the preview CroppedBitmap firstFrame = new CroppedBitmap(); firstFrame.BeginInit(); firstFrame.Source = sourceTexture; firstFrame.SourceRect = new Int32Rect(iAnimOffsetX, iAnimOffsetY, iFrameWidth, iFrameHeight); firstFrame.EndInit(); //apply the source worldPreview.Source = firstFrame; worldPreview.Stretch = Stretch.Fill; //resize the image to match the given object dimensions and aspect ratio string[] aspectRatioTerms = PreviewAspectRatio.SelectedValue.ToString().Split(':'); //calculate the aspect ratio as a float int iAspectWidth = int.Parse(aspectRatioTerms[1]); int iAspectHeight = int.Parse(aspectRatioTerms[2]); float fAspectRatio = (float)iAspectWidth / (float)iAspectHeight; //apply the aspect ratio to the frame's wdith fWorldWidth *= fAspectRatio; //determine wether to stretch the image horizontally or vertically so it can be as large as possible in the preview box float worldDimensionRatio = fWorldWidth / fWorldHeight; float wrapperDimensionRatio = (float)(worldPreviewWrapper.ActualWidth / worldPreviewWrapper.ActualHeight); //if the image is stretched further horizontally if (worldDimensionRatio > wrapperDimensionRatio) { worldPreview.Width = Math.Abs(worldPreviewWrapper.ActualWidth - 2); worldPreview.Height = Math.Abs((1 / worldDimensionRatio) * (worldPreviewWrapper.ActualWidth - 2)); } //if the image is strectched further vertically else { worldPreview.Width = Math.Abs((worldDimensionRatio) * (worldPreviewWrapper.ActualHeight - 2)); worldPreview.Height = Math.Abs(worldPreviewWrapper.ActualHeight - 2); } } } //indicate the given animation properties are invalid else { frameWidth.Background = new SolidColorBrush(Colors.Orange); frameHeight.Background = new SolidColorBrush(Colors.Orange); } } }
void LoadAnimation(string key) { #region Saving Current Animation //If there's animation open, we save it if (_AnimationDefinition["Name"] != "") { //ensure the current collsion polygon is saved LoadCollisionPolygon(int.Parse(CurrentFrame.Text), int.Parse(CurrentFrame.Text)); /* Writing is done in a new thread because using try/catch automatically creates a new thread, * which would allow the new animation to be loaded before the current one is saved */ animationSave = new Thread(new ParameterizedThreadStart(SaveAnimation)); animationSave.Start(); animIndexSave = new Thread(new ParameterizedThreadStart(SaveAnimationsIndex)); animIndexSave.Start(); //wait for the animation to be save before continuing animationSave.Join(); animIndexSave.Join(); } #endregion #region Load Selected Animation StreamReader inStream = null; try { //open the animation definition inStream = new StreamReader(System.IO.Path.Combine(Settings.projectDirectory, Settings.animationDefsDir, key + "." + Settings.animationExt)); //Load in the information about the animation _AnimationDefinition.Clear(); _AnimationDefinition.Add("Name", inStream.ReadLine()); _AnimationDefinition.Add("Texture", inStream.ReadLine()); _AnimationDefinition.Add("Frames", inStream.ReadLine()); _AnimationDefinition.Add("Frame Dur.", inStream.ReadLine()); _AnimationDefinition.Add("Frame Width", inStream.ReadLine()); _AnimationDefinition.Add("Frame Height", inStream.ReadLine()); _AnimationDefinition.Add("Offset X", inStream.ReadLine()); _AnimationDefinition.Add("Offset Y", inStream.ReadLine()); _AnimationDefinition.Add("Obj Width", inStream.ReadLine()); _AnimationDefinition.Add("Obj Height", inStream.ReadLine()); //re-bind the definition to the display AnimationInfo.ItemsSource = AnimationDefinition; //reset the current frame CurrentFrame.Text = "0"; //set the quick-access frame count frameCount = int.Parse(_AnimationDefinition["Frames"]); //reset the collision polygon array (there might not be any for a given animation) collisionPolygons = new List <PolygonData> [int.Parse(_AnimationDefinition["Frames"])]; //instantiate each list in the collision polygon array for (int i = 0; i < frameCount; i++) { collisionPolygons[i] = new List <PolygonData>(); } //if a collision polygon is defined, load it string collisionRectsString; if ((collisionRectsString = inStream.ReadLine()) != null) { //split the string into frames (delimted by ;), and then into individual polygon properties (denoted by ,) string[][] collisionInfo = collisionRectsString.Split(';').Select(s => s.Split(',')).ToArray(); //process the polygon data for each frame for (int i = 0; i < frameCount; i++) { //the definition won't necessarily end nicely, so its easier just to wait for an error than try to prevent it try { //create a rectangle from each set of properties //format in file is left,top,width,height for (int p = 0; p < collisionInfo[i].Length; p += 4) { //again, things won't always come out nicely try { string[] typePcs = collisionInfo[i][p].Split(':'); int type = 0; double left; if (typePcs.Length > 1) { type = int.Parse(typePcs[0]); left = double.Parse(typePcs[1]); } else { left = double.Parse(collisionInfo[i][p]); } double top = double.Parse(collisionInfo[i][p + 1]); double width = double.Parse(collisionInfo[i][p + 2]); double height = double.Parse(collisionInfo[i][p + 3]); collisionPolygons[i].Add(new PolygonData(left, top, width, height, (PolygonType)type)); } catch (IndexOutOfRangeException) { Console.WriteLine("Reached end of polygon def"); } catch (Exception ex) { Console.Write(ex.Message); } } } catch (IndexOutOfRangeException) { Console.WriteLine("No more frames"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } customFields.Clear(); for (int f = 0; f < Settings.customFields.Length; f++) { customFields.Add(new AnimationProperty(Settings.customFields[f], inStream.ReadLine() + "")); } //get the file name of the current texture string textureName = textures[_AnimationDefinition["Texture"]].Split('/', '\\').Last(); //Load in a png fo the current texture currentTexture = new BitmapImage(); try { currentTexture.BeginInit(); string uri = System.IO.Path.Combine(Directory.GetCurrentDirectory(), Settings.projectDirectory, Settings.animationSheetDir, textureName + ".png"); currentTexture.UriSource = new Uri(uri); } catch (FileNotFoundException e) { MessageBox.Show("Source preview image for animation '" + key + "' not found at " + e.FileName); } finally { currentTexture.EndInit(); } //get the draw properties of the current animation int fWidth = int.Parse(_AnimationDefinition["Frame Width"]); int fHeight = int.Parse(_AnimationDefinition["Frame Height"]); int aOffsetX = int.Parse(_AnimationDefinition["Offset X"]); int aOffsetY = int.Parse(_AnimationDefinition["Offset Y"]); //draw a specific portion of the texture (the first frame) CroppedBitmap frame = new CroppedBitmap(); frame.BeginInit(); frame.Source = currentTexture; frame.SourceRect = new Int32Rect(aOffsetX, aOffsetY, fWidth, fHeight); frame.EndInit(); //apply the texture & draw rectangle to the Image control Texture.Stretch = Stretch.Fill; Texture.Source = frame; Texture.Width = fWidth; Texture.Height = fHeight; TextureBorder.Width = fWidth; TextureBorder.Height = fHeight; Console.WriteLine(Texture.ActualWidth + " " + Texture.ActualHeight); //load the collision polygon for the first frame LoadCollisionPolygon(0); } catch (FileNotFoundException e) { MessageBox.Show("Animation definition file for '" + key + "' does not exist at " + e.FileName); } catch (Exception ex) { MessageBox.Show("Error Loading Animation: " + ex.Message); } finally { if (inStream != null) { inStream.Close(); } } #endregion }
//Track frame in textbox void CurrentFrame_TextChanged(object sender, EventArgs e) { TextBox input = sender as TextBox; int intVal; //make sure the value of the input is valid if (int.TryParse(input.Text, out intVal)) { if (intVal >= 0 && intVal < frameCount && currentTexture != null) { //load the new collision polygon and saves the current one LoadCollisionPolygon(intVal, previousFrame); //Display the correct frame of animation //get the properties of the animation from the definition int fWidth = int.Parse(_AnimationDefinition["Frame Width"]); int fHeight = int.Parse(_AnimationDefinition["Frame Height"]); int aOffsetX = int.Parse(_AnimationDefinition["Offset X"]); int aOffsetY = int.Parse(_AnimationDefinition["Offset Y"]); //get the max number of rows and columns of frames per sheet for this animation int maxRowFrames = 2048 / fWidth; int maxColumns = 2048 / fHeight; //Determines what row to point to based on the current frame //and the maximum frames in a row int row = intVal / maxRowFrames; //Determines column to point to based on currentframe and max frames int column = intVal % maxRowFrames; int spriteSheet = intVal / (maxRowFrames * maxColumns); //calculate the frame offsets int frameOffsetX = column * fWidth + aOffsetX; int frameOffsetY = (row - (spriteSheet * maxColumns)) * fHeight + aOffsetY; //get the file name of the current texture string textureName = textures[_AnimationDefinition["Texture"]].Split('/', '\\').Last() + ((spriteSheet > 0) ? spriteSheet.ToString() : ""); //Load in a png fo the current texture currentTexture = new BitmapImage(); currentTexture.BeginInit(); string uri = System.IO.Path.Combine(Directory.GetCurrentDirectory(), Settings.projectDirectory, Settings.animationSheetDir, textureName + ".png"); currentTexture.UriSource = new Uri(uri); currentTexture.EndInit(); //unlike xna, wpf will crash if it tries to access any portion of the image beyond its dimensions, so try to ensure the source box is inside the image if (frameOffsetX + fWidth > currentTexture.PixelWidth) { fWidth = (int)currentTexture.PixelWidth - frameOffsetX; } if (frameOffsetY + fHeight > currentTexture.PixelHeight) { fHeight = (int)currentTexture.PixelHeight - frameOffsetY; } //create the new frame CroppedBitmap frame = new CroppedBitmap(); frame.BeginInit(); frame.Source = currentTexture; frame.SourceRect = new Int32Rect(frameOffsetX, frameOffsetY, fWidth, fHeight); frame.EndInit(); //setup the image to render the frame Texture.Stretch = Stretch.Fill; Texture.Source = frame; Texture.Height = fHeight; Texture.Width = fWidth; TextureBorder.Width = fWidth; TextureBorder.Height = fHeight; previousFrame = intVal; } else { //if (intVal < 0) intVal = 0; //if (intVal >= frameCount) intVal = frameCount - 1; intVal = previousFrame; } input.Text = intVal.ToString(); } else { CurrentFrame.Text = previousFrame.ToString(); } }