1

I am having a problem loading a pgn file in WPF using VS 2008 3.5 framework. The file loads and displays ok, but the size is off. I have researched other questions, and have tried various suggestions, but to no avail.

I started with an image in a pgn file that was 36 x 50. I then used Windows Paint to reduce it in size to 29 x 40. I load it into a System.Windows.Media.Imaging.Bitmap object and then use that as the source for a System.Windows.Controls.Image object. When the image is displayed, it appears larger than the same image in Paint. Here is what I have done to try to fix the problem:

  1. Verified that the file read in has the proper width and height. looked at the bitmap object in the debugger and it says the width = 29 and the height = 40. Verified that the system dpi is set to 96 from code at this link.

  2. Set Stretch = none. Has had no effect.

  3. Tried using the System.Drawing.Image object to view the pgn file horizontal and vertical resolution. They are both set to 96.

  4. Tried using pgnout, which is a pgn file compression program on some of my file images. It is also supposed to set the image resolution to 96. It had no effect on the size of the displayed images.

  5. Tried comparing the size displayed against different size images. It appears that the displayed height is 31 pixels. The width is about 34 pixels. Have tried using other editors like Paint.Net and Gimp, but they produce the same results as Paint.

I'm running out of ideas. The only work around I see is to go into Paint and readjust all my images to a smaller size so that they will be the right size when displayed in WPF.

Here is my code for loading a pgn file and creating an image:

private void LoadCardbackBitmapFromFile()
{
   // This method loads the cardback image from the pgn file.
   //
   string CardBackFileName = AppSettings.CardsbackFolder + @"\" + AppSettings.CardsBackFileName + AppSettings.CardsBackIndex.ToString() + ".png";
   // Check if the file exists.
   if (!File.Exists(CardBackFileName))
   {
      StringBuilder SBLog = new StringBuilder("AttackPoker2::Cards::Cards - unrecoverable error - could not find the card back file " + CardBackFileName.ToString() + ".\n");
      SSLSocketInterface.LogMsgCPP(SBLog, LogLevel.LogInfo);
      string S = "Unrecoverable error - could not find the card back file " + CardBackFileName.ToString() + ".\nInstallation may be corrupt.  Try re-installing or re-locating the cards folder.";
      throw new ApplicationException(S);
   }
   CardbackBitmap = new BitmapImage();
   CardbackBitmap.BeginInit();
   CardbackBitmap.UriSource = new Uri(CardBackFileName, UriKind.Absolute);
   CardbackBitmap.CacheOption = BitmapCacheOption.OnLoad;
   CardbackBitmap.EndInit();
   CardbackImage = new Image();
   CardbackImage.Source = CardbackBitmap;
   CardbackImage.Stretch = Stretch.None;
   CardbackImage.VerticalAlignment = VerticalAlignment.Top;
   CardbackImage.HorizontalAlignment = HorizontalAlignment.Left;
}

private void CreateCardbackImages()
{
   // This method creates clones of the cardback image so that they can be displayed simultaneously.  WPF does not provide the capability to reuse ui objects.
   //
   for (int SeatLoop = 0; SeatLoop < NumSeats; SeatLoop++)
   {
      for (int CardLoop = 0; CardLoop < NumPlayerCards; CardLoop++)
      {
         Image CBI = new Image();
         CBI.Source = CardbackImage.Source;
         CBI.Stretch = CardbackImage.Stretch;
         // Set the card so it is not viewable.
         CBI.Visibility = Visibility.Collapsed;
         CardbackImages[SeatLoop, CardLoop] = CBI;
         CardsGrid.Children.Insert(SeatLoop, CBI);
      }
   }
}
//
private Grid LayoutRoot; // The main ui grid.
private Grid CardsGrid; // Used to place the the card images.
private BitmapImage CardbackBitmap; // Used to hold the image read in from the pgn file.
private static Image CardbackImage; // Used to hold the original cardback image.
private Image[,] CardbackImages; // Holds the list of cardback images used to deal the cards to each player. 1st dim is the seat; 2nd dim is the card number.

Here is the XAML:

<Window x:Class="A2.GameWindow" Width="600" Height="497"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Closing="GameWindow_Closing">
  <Viewbox HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="Fill">
    <Grid Name="LayoutRoot">
      <Grid.RowDefinitions>
        <RowDefinition Height="0.85*"/>
        <RowDefinition Height="0.15*"/>
      </Grid.RowDefinitions>
         <Image Source="Table Green.png" Stretch="Fill"/>
         <TabControl Grid.Row="1" FontSize="9" FontFamily="Fonts/#Segoe UI Semibold" FontWeight="Bold">
          <TabItem Header="Chat">
            <StackPanel>
              <TextBox Name="TxtTyping" Width="193.75" FontSize="8" MaxLines="1" Margin="-285,0,0,0"></TextBox>
              <TextBox Name="TxtMessages" Width="193.75" Height="64.125" FontSize="8" Margin="-285,0,0,0" Background="#FFC8F0EC"></TextBox>
            </StackPanel>
          </TabItem>
          <TabItem Header="Notes">
            <StackPanel>
              <ComboBox Name="NotesCombo" Width="193.75" Margin="-285,0,0,0"></ComboBox>
              <TextBox Name="TxtNotesMessages" Width="193.75" Height="64.125" Margin="-285,0,0,0"></TextBox>
            </StackPanel>
          </TabItem>
          <TabItem Header="Stats">
              <TextBox Name="TxtStats" Width="193.75" Height="64.125" Margin="-285,0,0,0" Background="#FFC8F0EC"></TextBox>
          </TabItem>
           <TabItem Header="Info">
              <TextBox Name="TxtInfo" Width="193.75" Height="64.125" Margin="-285,0,0,0" Background="#FFC8F0EC"></TextBox>
          </TabItem>
        </TabControl>
      </Grid>
    </Viewbox>
</Window>

Does anyone have any ideas what the problem might be? How can I make an image display the same size in WPF as it does in Paint and other image editors? Am I doing anything wrong? Any suggestions would be appreciated.

Community
  • 1
  • 1
Bob Bryan
  • 3,687
  • 1
  • 32
  • 45
  • 1
    WPF UI elements layout might also depend on the containers' layout. Post the relevant XAML. – Federico Berasategui Jun 03 '13 at 20:43
  • 1
    By the way, you seem to be using a (dinosaur) winforms approach to this. You should be doing this the (right) MVVM way in WPF. – Federico Berasategui Jun 03 '13 at 20:45
  • 3
    Dude, your UI is inside a `Viewbox`. It's never going to look the same as external applications, It's being stretched to the available space. – Federico Berasategui Jun 03 '13 at 20:58
  • Same question here: http://stackoverflow.com/questions/3055550/wpf-how-to-display-an-image-at-its-original-size – Pedro77 Jun 03 '13 at 21:23
  • @HIghCore This is my first WPF project. I appreciate your suggestions. If the entire window is within a ViewBox control - with the idea being that when the user increases the window size everything inside that window expands as well - how should the original user interface (ui) elements be designed or laid out such that the desired size of the ui elements from an image editor is maintained? Or perhaps I should ask - is it even possible for this to be done? I suppose that the window size can be reduced or the ui elements can be reduced. Any other ideas? – Bob Bryan Jun 03 '13 at 21:38
  • When the ViewBox Stretch property is set to Fill, or UniformFill, it does not show the right size. However, when the Stretch property is set to Uniform, then it comes much closer to displaying the proper size. It is still a little too big. Wish I had a better understanding of how the ViewBox control decides when to stretch things. I had thought that it would not adjust the size when the window is first loaded. But, that does not appear to be the case. I also verified that the correct size is displayed when stretch is set to None. – Bob Bryan Jun 03 '13 at 23:02
  • Hey Bob, have you looked at the link that I've posted? http://stackoverflow.com/questions/3055550/wpf-how-to-display-an-image-at-its-original-size Yes, Stretch="None" will keep image scale to 100%. You can also change the ImageBox size to the same size of the image. – Pedro77 Jun 04 '13 at 13:59

1 Answers1

1

Almost same question here: WPF: How to display an image at its original size?

Stretch="None" will keep image scale to 100%.

You can also change the ImageBox size to the same size of the image.

Some samples:

To keep the aspect ratio

imageBox.Stretch="None"

To change the size:

imageBox.Width = myImage.Width ;
imageBox.Height = myImage.Height;

To limit the max size:

if (imageBox.ActualHeight > 500)
    imageBox.Height = 500;

if (imageBox.ActualWidth > 800)
     imageBox.Width = 800;
Community
  • 1
  • 1
Pedro77
  • 5,176
  • 7
  • 61
  • 91
  • Thanks for the answer. I did research the link you listed above before posting the question. My issue has nothing to do with that question. My issue has to do with the fact that the window is inside a ViewBox object, and the fact that the ViewBox object does not seem to display objects to their actual size upon window creation even if stretch is set to Uniform. I don't know how to load a ui element and show it at the original size when it is first loaded within a ViewBox at app startup. That is the issue. ViewBox does something to the scaling and I don't know what that is. – Bob Bryan Jun 04 '13 at 18:17
  • I am not using an ImageBox object. I am using System.Windows.Media.Imaging.Bitmap to read the file in. I am then using a System.Windows.Controls.Image object to display the object. Also, I have verified that the width and height for the bitmap object read in is correct, so setting it to the same value would have no effect. I mentioned this in the question. – Bob Bryan Jun 04 '13 at 18:24