locked
BitmapSource confusion RRS feed

  • Question

  • Hello all, I'm getting back into C# development after a long hiatus and I'm a bit rusty so please bear with me.

     

    I'd like to do some image processing and I've been looking into the WPF imaging subsystem which, as I understand it, is based on WIC. I've read that the "BitmapSOurce" is the base class from which the other classes in WIC are derived, but I'm confused by the following code in the Microsoft docs:

     

    // Create a BitmapSource.
    BitmapSource bitmap = BitmapSource.Create(width, height,
      96, 96, pf, null,
      rawImage, rawStride);
    
    // Create an image element;
    Image myImage = new Image();
    myImage.Width = 200;
    // Set image source.
    myImage.Source = bitmap;

     

    It appears as though "BitmapSource" is some sort of static class as its "Create(...)" method is not being invoked from the specific context of an instantiated object. But then it is also being used as if it were an instantiated object by being assigned to the "Source" property of the "image" control. Put another way, it looks as if the "Create" method of the static class "BitmapSource" is being used to instantiate an instance of the "BitmapSource" static class which is referred to as "bitmap"?!?  As you can see I'm a little confused here...can someone please set me straight? Thanks in advance!

    Tuesday, November 30, 2010 6:31 PM

Answers

  • Hi LKeene,

    I think you are confuse the static class and the static method. First of all, let us to see the class definition of the BitmapSource class:

    public abstract class BitmapSource : ImageSource, DUCE.IResource
    {
     ......
     // Methods
     static BitmapSource(); // Static constructor of this class
     ...... // Other properties and methods
     
     public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, Array pixels, int stride);
     public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, IntPtr buffer, int bufferSize, int stride);
     
    }
    
    
    

    BitmapSource class is abstract, not static, so we can not instantiate it, we could instantiate the sub class such as BitmapImage class. But BitmapSource provides the static mthod that can hellp us to create a BitmapSource instance (actually it is a CachedBitmap instacne) without instantiate the class. About abstract and static in C#, pleaser refer to the documents: abstract (C# Reference) and static (C# Reference)

    When we design a class, we usually need one class to define some common methods and some common properties, we call it "base class"; But we do not want it to be instantiated, why, since a class in the world may not be created, for example, we have an "Animal" class inthe world. There is no a object is called "Animal", we only know one which is called "Cat", and the other is a "Dog". So here, we should specify an abstract key on the "Animal" class, that the "Animal" class cannot be instantiated in the world.

    However, eve if we cannot know the specific type of the "Animal", we also want to create an general instance of the "Animal", we could define the default values for the "Animal" instance, like "Skin", "Birthplace" etc. They are the common properties that all kinds of the animal should have. So the "Animal" class can have a static method to create the an general instance (it may be called "Cat" in default, just an analogy), and then we could add other features on this general instance.

    Above is an analogy, back to our BitmapSource class or other classes in .Net Framework. We can imagine, no one class can contain all features of the inherited classes. But sometime, the user do not know what kinds of the inherited classes we can use. For BitmapSource class, we may use the CachedBitmap or the BitmapImage or others, And we just want to create one BitmapSource instance that we could do the common operations on it, can set the common properties, so BitmapSource class share a static method to create an instance (a CachedBitmap instacne) itself. According to the descritpion of the abstract document: Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class. BitmapSource.Create() method creates an inherited class of the BitmapSource -- CachedBitmap:

    public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, Array pixels, int stride)
    {
     return new CachedBitmap(pixelWidth, pixelHeight, dpiX, dpiY, pixelFormat, palette, pixels, stride);
    }
    
    
    

    I may not explain it clearly, if you have any other problems, please feel free to let me know.

    Sincerely,
    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Are you looking for a typical code sample? Please download All in One Code Framework !

    如果有回复帮助并解决了您的问题,请点击 “标记为答复”,如果没有没有帮助,请随时点击“取消答复标记”
    你在为寻找代码示例而苦恼吗?赶快来下载 All in One Code Framework 微软一站式代码框架 吧!
    • Marked as answer by LKeene Wednesday, December 1, 2010 9:24 PM
    Wednesday, December 1, 2010 5:35 AM

All replies

  • Sounds like you getting tripped up by the Public Shared Function Create.  Public Shared functions do not require an object instance.    Read the MSDN on Shared Functions to get a better idea why they are sometimes useful.  With that said bitmap does get instantiated from the output of the function BitmapSource.Create.  Finally the image source is set to the bitmap instance that was just created.

    Hope this helps.

    Here is a link to the function: http://msdn.microsoft.com/en-us/library/ms616045.aspx

    Tuesday, November 30, 2010 6:43 PM
  • Thank you for the helpful reply. I'll read up on shared functions. I'm a little shell-shocked by the massive changes that this language has undergone since my time off. I'd say a good 15-20% of the code i'm reading I no longer recognize or understand due to all the new language features.

     

    One other thing: you say that "bitmap" does get instantiated from the output of the "BitmapSource.Create" function. The MSDN docs are listing "BitmapSource" as an abstract class and hence it cannot be directly instantiated, no? Unless this has changed as well?

    Tuesday, November 30, 2010 6:54 PM
  • Okay, I now understand that this is a static method in an abstract class ("shared" must have been in reference to the VB jargon). There is still the strange issue of instantiating an abstract class, however.

     

    -l

    Tuesday, November 30, 2010 7:00 PM
  • Correct, you cannot create and Instance of BitmapSource since it is declared as a MustInherit class.  However using the NameSpace BitmapSource gives you access to its Public Shared methods since an instance is not required.

    Sorry, I see what your saying now.  Its confusing that the function Create is returning an Instance of BitmapSource since it cannot be instantiated.  Saying it can't be instantiated is false (sorry), you can create an instance of BitmapSource within the scope of the class BitmapSource (ie: if u were making a copy constructor, or in this case the Shared Function Create).  Outside the scope of the class, you would have to inherit BitmapSource into another class to Instantiate it.

    • Edited by KP_SES Tuesday, November 30, 2010 7:16 PM edited
    Tuesday, November 30, 2010 7:06 PM
  • Hi KP_SES,

     

    forgive me, I'm trying to go back and forth between VB (which I don't know) and C#. I can deduce the following: "Public Shared"(VB) = "public static"(C#), and "MustInherit"(VB) = "abstract"(C#). How, then, can an object be instantiated from a class labelled with the MustInherit keyword, as it appears to be in the original example?

    Tuesday, November 30, 2010 7:13 PM
  • Yes, sorry I program in VB all day long and I forget the terms are changed in C#.  Someone will correct me if I'm wrong, but its a matter of scope.  You can create an Instance of BitmapSource within the scope of the class BitmapSource.
    Tuesday, November 30, 2010 7:19 PM
  • Hi LKeene,

    I think you are confuse the static class and the static method. First of all, let us to see the class definition of the BitmapSource class:

    public abstract class BitmapSource : ImageSource, DUCE.IResource
    {
     ......
     // Methods
     static BitmapSource(); // Static constructor of this class
     ...... // Other properties and methods
     
     public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, Array pixels, int stride);
     public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, IntPtr buffer, int bufferSize, int stride);
     
    }
    
    
    

    BitmapSource class is abstract, not static, so we can not instantiate it, we could instantiate the sub class such as BitmapImage class. But BitmapSource provides the static mthod that can hellp us to create a BitmapSource instance (actually it is a CachedBitmap instacne) without instantiate the class. About abstract and static in C#, pleaser refer to the documents: abstract (C# Reference) and static (C# Reference)

    When we design a class, we usually need one class to define some common methods and some common properties, we call it "base class"; But we do not want it to be instantiated, why, since a class in the world may not be created, for example, we have an "Animal" class inthe world. There is no a object is called "Animal", we only know one which is called "Cat", and the other is a "Dog". So here, we should specify an abstract key on the "Animal" class, that the "Animal" class cannot be instantiated in the world.

    However, eve if we cannot know the specific type of the "Animal", we also want to create an general instance of the "Animal", we could define the default values for the "Animal" instance, like "Skin", "Birthplace" etc. They are the common properties that all kinds of the animal should have. So the "Animal" class can have a static method to create the an general instance (it may be called "Cat" in default, just an analogy), and then we could add other features on this general instance.

    Above is an analogy, back to our BitmapSource class or other classes in .Net Framework. We can imagine, no one class can contain all features of the inherited classes. But sometime, the user do not know what kinds of the inherited classes we can use. For BitmapSource class, we may use the CachedBitmap or the BitmapImage or others, And we just want to create one BitmapSource instance that we could do the common operations on it, can set the common properties, so BitmapSource class share a static method to create an instance (a CachedBitmap instacne) itself. According to the descritpion of the abstract document: Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class. BitmapSource.Create() method creates an inherited class of the BitmapSource -- CachedBitmap:

    public static BitmapSource Create(int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, Array pixels, int stride)
    {
     return new CachedBitmap(pixelWidth, pixelHeight, dpiX, dpiY, pixelFormat, palette, pixels, stride);
    }
    
    
    

    I may not explain it clearly, if you have any other problems, please feel free to let me know.

    Sincerely,
    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Are you looking for a typical code sample? Please download All in One Code Framework !

    如果有回复帮助并解决了您的问题,请点击 “标记为答复”,如果没有没有帮助,请随时点击“取消答复标记”
    你在为寻找代码示例而苦恼吗?赶快来下载 All in One Code Framework 微软一站式代码框架 吧!
    • Marked as answer by LKeene Wednesday, December 1, 2010 9:24 PM
    Wednesday, December 1, 2010 5:35 AM
  • Thanks for that great writeup Bob! could you elaborate a little on what you mean when you say we can create an "instance" of an abstract class...what is the difference between a class "instance" and an "instantiated" class?
    Wednesday, December 1, 2010 5:21 PM
  • Hi LKeene,

    Just 2 cents after detailed reply from Bob.

    You can call a static / Shared method using class name. That is why you see BitmapSource.Create(...) working.

    The other important thing is the return type of Create method. This is based on the same old OOP concept of Polymorphism. This is an abstract class. We can even specify an interface as return type. This means that whatever class which implements that interface an be returned by this method. In the same way, for Create, the instance whatever class inheriting from BitmapSource can be returned here. You can assign it to a BitmapSource or any inherited class reference.

    So, We can not instantiate BitmapSource but we can certainly assign a subclass instance to a BitmapSource reference because of Polymorphism.

    I hope this helped!

    Muhammad
    shujaatsiddiqi.blogspot.com


    Muhammad Siddiqi
    Wednesday, December 1, 2010 5:40 PM
  • Okay I see what's happening now. Thanks for all the help everyone.

     

    -L

    Wednesday, December 1, 2010 9:24 PM