I know that OOP is about encapsulating data and behavior together, but I don't think it's a good idea for an Image to have the resize logic embedded in this case, because an Image doesn't need to know how to resize itself to be an Image.
A thumbnail is actually a different Image. Perhaps you might have a datastructure that holds the relationship between a Photograph and it's Thumbnail (both of which are Images).
I try to divide my programs into things (like Images, Photographs, Thumbnails, etc.) and Services (like PhotographRepository, ThumbnailGenerator, etc.). Get your data structures right, and then define the services that let you create, manipulate, transform, persist and recover those data structures. I don't put any more behavior in my data structures than making sure they're created properly and used appropriately.
Therefore, no, an Image shouldn't contain the logic about how to make a Thumbnail. There should be a ThumbnailGenerator service that has a method like:
Image GenerateThumbnailFrom(Image someImage);
My bigger data structure might look like this:
class Photograph : Image
{
public Photograph(Image thumbnail)
{
if(thumbnail == null) throw new ArgumentNullException("thumbnail");
this.Thumbnail = thumbnail;
}
public Image Thumbnail { get; private set; }
}
Of course that might mean you're doing effort you don't want to do while constructing the object, so I would consider something like this OK too:
class Photograph : Image
{
private Image thumbnail = null;
private readonly Func<Image,Image> generateThumbnail;
public Photograph(Func<Image,Image> generateThumbnail)
{
this.generateThumbnail = generateThumbnail;
}
public Image Thumbnail
{
get
{
if(this.thumbnail == null)
{
this.thumbnail = this.generateThumbnail(this);
}
return this.thumbnail;
}
}
}
... in the case where you want a data structure with lazy evaluation. (Sorry I didn't include my null checks and I didn't make it thread-safe, which is something you'd want if you were trying to mimic an immutable data structure).
As you can see, either of these classes is being built by some kind of PhotographRepository, which probably has a reference to a ThumbnailGenerator that it got through dependency injection.