I have an awkward question. I think it's impossible but I need to know for sure. It's a bit of an odd request, but I need my child classes to share the SAME Pixels vector from the parent class.
Basically, I want to create an instance of Image class. That Image class will hold Pixels for both Bitmap and Png Class so that if I need to convert from Bitmap To PNG and Vice-versa, they use the same vector rather than me creating both Bitmap and PNG classes.
class Image
{
private:
std::vector<RGB> Pixels;
};
class Bitmap : Image
{
public:
Bitmap() : Image() {};
};
class Png : Image
{
public:
Png() : Image() {};
};
Such that when I do:
int main()
{
Image Img();
Img.GetBitmapPixels(); //This
Img.GetPngPixels(); //And this, return the same Pixels Vector.
Bitmap Foo = Img.ToPng();
Png Moo = Img.ToBitmap();
//Such that both Foo and Moo have the exact same underlying Pixels Vector.
}
Currently my classes look like:
class Bitmap
{
private:
std::vector<RGB> Pixels;
public:
Bitmap();
std::vector<RGB> GetPixels() {return Pixels;}
void SetPixels(std::vector<RGB> Pixels) {this->Pixels = Pixels;}
};
class Png
{
private:
std::vector<RGB> Pixels;
public:
Png();
std::vector<RGB> GetPixels() {return Pixels;}
void SetPixels(std::vector<RGB> Pixels) {this->Pixels = Pixels;}
};
And to convert from one to the other, I have to do:
int main()
{
Bitmap Bmp();
Png PNG();
PNG.SetPixels(BMP.GetPixels); //BMP has to COPY PNG's Pixels and vice-versa..
}
It's kind of a stupid question. I just don't want to copy pixels. I just want to be able to convert between the two classes without any copying as both classes hold an std::vector Pixels member and the data is aligned the same.
I guess I'm trying to be able to do: PNG.SaveAsBitmap(...); Or BMP.SaveAsPNG(...); without creating a new instance of the other.
How can I avoid copying/creating and making a new instance of the other class I'm converting to? Can I have classes that inherit from eachother?
I may be oversimplyfying this. How are you loading your data? If it is the same for each image type could you have a load in the image class and just overload the Translation functions. I am not an expert on image data but could you do something similiar to:
public Image
{
private Pixels data;
public void GetPixels();
public virtual Pixels ToFormat(FormatEnum format);
}
public Bitmap:Image
{
public override Pixels ToFormat(FormatEnum format)
{
switch(format){
case FormatEnum.Bitmap:return data;break;
case FormatEnum.Png:return doSomethingElse();break;
}
}
}
int main()
{
Image Img();
Img.GetPixels();
Bitmap Foo = Img.ToFormat(Format.BitMap);
Png Moo = Img.ToFormat(Format.Png);
}
Since they share a parent as a common factor, you can elect to use pointers (this is considered a shallow copy), but this is usually not wise a deep copy is usually better. Perhaps you can create two functions one to create a shallow copy and one for a deep copy. Since a Bitmap and a Png are separate entities (they are siblings). Perhaps you should allow BMP to be the parent of png?
You may also elect to decouple the encoding altogether for saving purposes and just deal with the raw image data.
Related
I hope you can help me because I'm trying to improve my C++ inheritance concepts. First of all, I have the following object hierarchy:
A base class "Image" with two child classes: PNG and JPG (each one with their methods).
I wrote a method inside PNG class which (in a simulated way) deletes alpha channel (it just prints "Alpha channel deleted").
That being said, I want to write a method which takes an array of many pointers to image objects (can be either JPG or PNG) as input, and deletes the alpha channel of only those which are PNG. Since it isn't a good practice in C++ ask for the type of the object (or so I believe), which is the best way to loop through the image array (remembering that it could be filled with either PNG or JPG objects) and delete the alpha channel of only the PNG objects? In which class should I write that method? Parent or child?
I hope I've explained myself correctly, and thank you very much in advance.
The obvious implementation is that the base class has a virtual method for deleting the alpha channel that is a no-op. The PNG class inherits from Image and overrides this member function.
class Image
{
public:
virtual void DeleteAlphaChannel() {};
};
class PNG : public Image
{
void DeleteAlphaChannel() override
{
cout << "Alpha Channel deleted" << endl;
}
};
Then a helper function that takes an array of Image pointers, hence Image**
void DeleteAlphaChannelsFromArrayOfObjects(Image** imageList, int count)
{
for (int i = 0; i < count; i++)
{
imageList[i]->DeleteAlphaChannel();
}
}
And corresponding sample code.
{
PNG pngFile("foo.png");
JPG jpgFile("bar.jpg");
Image* imageList[2] = {&pngFile, &jpgFile};
DeleteAlphaChannelsFromArrayOfObjects(imageList, 2);
}
You could also do a vector style implementation:
void DeleteAlphaChannelsFromArrayOfObjects(std::vector<Image*>& imageList)
{
for (Image* pImage : images)
pImage->DeleteAlphaChannel();
}
I think the problem is quite basic and there was the same Question for sure somewhere here but i wasn't able to find.
So here is the Problem. Top has access to MyCircle and calls the SetSize function. But MyCircle has no access to MyRect.
I am able to access MyRect if i am providing a pointer to MyRect within the Constructor of MyCircle, but i think there should be another way. Maybe i just got it wrong at all :( Thanks for your help.
in the
class Top{
public:
Rect myRect;
Circle myCircle;
void Run();
};
class Rect{
public:
int size;
};
class Circle{
public:
int size;
void SetSize(int buffer);
};
void Circle::SetSize(int buffer){
myRect.Size = buffer;
}
void Top:Run(){
myCircle.SetSize(10);
}
Don't pass a rectangle to a circle class, the circle should have no knowledge about the rectangle (or vice versa).
Instead make a function in Top using both the circle and rect and act on that.
I don't know exactly what you want to do, but suppose you want to set the sizes equally. Than make e.g. a SetSize method in Top setting the sizes for both the circle and rectangle:
e.g.
class Top{
public:
Rect myRect;
Circle myCircle;
void Run();
void SetSize(int size)
}
where SetSize is implemented as:
myRect.SetSize(size);
myCircle.size = size;
It's always better to put code handling multiple derived objects in the base class instead of in one of the children. If there will be too much (or unrelated) functionality in the base class, create a different class (like SizeHandler).
btw, it's better not to use public properties but always get/set methods.
Brand new to c++, trying to figure out how to create a class that I can store a list of objects in.
I have a surface class with subclasses such as triangles, circles, ect.
I'm trying to create a class called Scene, that I can store a list of all the surfaces.
Here's the header file for what I'm trying to do. How do you do this in c++?
class Scene
{
private:
//background color elements
float bgRed;
float bgGreen;
float bgBlue;
//array of different surfaces
Surface surfaces[]; //<--- What I want
public:
Scene();
addSurface(Surface s);
};
There are many possibilities, here's a easy one with a std::vector:
vector<Surface> surfaces;
...
addSurface(const Surface &s) //const and & are not strictly necessary, but better
{
surfaces.push_back(s);
}
...
//accessing like an array: surfaces[index]
//element count: surfaces.size()
This copies the passed objects (s) while inserting. If you want the same object, so that changes in the vector affect the object "outside" too (and vice-versa), you'll need an additional pointer.
Also note that copying of an child class object of Surface will result in a pure Surface, without the child class part (object slicing). If you need that part, you'll need a pointer too (if you don't have one already).
//pointer variant
vector<Surface*> surfaces;
...
addSurface(Surface &s)
{
surfaces.push_back(&s);
}
I need some design suggestions for an Image class hierarchy.
Currently, I have 2 types of images (one is a standard image, the second doesn't contain standard image data).
Sometimes I want the object to allocate the memory for the image data, and other times I just want it to point to it.
The problem arises when I want to give TypeA images specific functionality.
If TypeA images inherit from Image, I will have to duplicate the functionality of the Allocated vs. non-Allocated Image.
I'm sure there is a better way to do this, I remember some elegant solutions with mixins during university, but can't find a way to use that here.
My current design looks like:
class Image
{
public:
Image(int width, int height, int bpp);
virtual ~Image() {};
// getters
template <typename T>
T* ptr() { return reinterpret_cast<T*>(m_imageData); } // T depends on bpp
protected:
// metadata
char* m_imageData;
};
class AllocImage : public Image
{
public:
AllocImage(int width, int height, int bpp, DataType dataType) :
Image(width, height, bpp, dataType)
{
m_imageData = new char[m_dataSize];
}
~AllocImage()
{
delete m_imageData;
}
};
class ImageHolder : public Image
{
public:
ImageHolder(int width, int height, int bpp, DataType m_dataType);
void setPtr(const void* ptr);
};
class AllocatedImageTypeA : public AllocImage
{
public:
// Type A specific methods
};
class NonAllocatedImageTypeA : public ImageHolder
{
public:
// duplicated Type A specific methods
};
If all the differences are constrained to how the image is held (allocated or not), you could use the policy model.
The short explanation is that you would pass a policy object to the image, where the policy describes whether you need to deallocate the image or not, how to access it, etc., basically anything that relates to the differences that arise from how the image data is held (allocated vs. pointed). Then all your access to the image will be through the policy.
For example, instead of writing
delete image;
You would write:
policy.del(image);
Where policy.del can be a delegate to delete or a no-op, depending on the actual type of the policy (that is in line with what the image requires)
Why so many types? If the difference is only in allocation, then simply create multiple constructors, one which takes a pointer to a pre-allocated data holder, one that doesn't and does the allocation internally. You could also use dependency injection to get the variations in behaviour / functionality.
I had a similar case.
Let's make something clear. Your class hierarchy its not based if an image is allocated or not, but, each class will have some features.
You may want to have a very specialized class that allocates images, another that references, and, warp that class with another of the same hierarchy, with similar features.
The following example, explains the idea of wraping one class, with another class,
from the same inheritance, that seems to apply to your questio.
Disclaimer: Please ignore, some minor bugs or non relevant syntax errors:
// generic base class for my image library:
/* abstract */ class GenericImage
{
public:
int width;
int height;
public:
/* constructor */ GenericImage() ;
/* destructor */ ~GenericImage() ;
/* constructor */ GenericImage(int newwidth, int newheight);
}; // class GenericImage
// in charge of allocating or deallocating an image
class AllocatedImage: GenericImage
{
public:
/* constructor */ AllocatedImage() ;
/* destructor */ ~AllocatedImage() ;
/* constructor */ AllocatedImage(int newwidth, int newheight);
/* constructor */ AllocatedImage(char* filename);
}; // class AllocatedImage
// access an image, but doesn't allocate or deallocate
class ContainedImage: GenericImage
{
public:
/* constructor */ ContainedImage() ;
/* destructor */ ~ContainedImage() ;
/* constructor */ ContainedImage(int newwidth, int newheight);
}; // class AllocatedImage
// real working class, will allocate other objects,
// of same hierarchy
class WrapperImage: GenericImage
{
public:
GenericImage* RealImage;
public:
/* constructor */ GenericImage() ;
/* destructor */ ~GenericImage() ;
void AllocateImage(AllocatedImage* newimage);
void HoldImage(ContainedImage* newimage);
}; // class AllocatedImage
Suggestions:
Its good idea, to have a constructor without parameters, specially if you are designing a class hierarchy, instead of a single class.
I know its a quick example, but, you may want to move all code to body file.
Cheers.
I have three classes, TImageProcessingEngine, TImage and TProcessing
TImageProcessingEngine is the one which i am using to expose all my methods to the world.
TImage is the one i plan to use generic image read and image write functions.
TProcessing contains methods that will perform imaging operations.
class TImageProcessingEngine
{
public:
TImage* mpImageProcessingEngine;
};
class TImage
{
public:
int ReadImage();
int WriteImage();
private:
//a two dimensional array holding the pixel values
tImageMatrix* mpImageMatrix;
};
class TProcessing
{
public:
int ConvertToBinary();
int ConvertToGrayScale();
};
My question is how do i access the object mpImageMatrix in class TProcessing? So that my calling application can use the following
TImageProcessingEngine* vEngine = new TImageProcessingEngine;
//Converts an input gray scsale image to binary image
vEngine->ReadImage().ConvertToBinary();
//Write the converted image to disk
vEngine->WriteImage();
delete vEngine;
vEngine = NULL;
//During this whole processing internally,
//the image is read in to `mpImageMatrix`
//and will also be holding the binarised image data,
//till writing the image to disk.
Or Do you recommend any other approach to my class design?
I would certainly recommend a different implementation, but let's check the design first.
I don't really understand the added value of TImageProcessingEngine, it doesn't bring any functionality.
My advice would be quite simple in fact:
Image class, to hold the values
Processing class (interface), to apply operations
Encoder and Decoder classes (interfaces), to read and write to different formats
It does make sense for the Processing class to have access to the images internal only if you can get efficiency from it (which is likely), in this case you can simply makes Processing friend and having it unpack the values for its derived
class Image
{
public:
Image();
void Accept(Processing& p);
void Encode(Encoder& e) const; // Image is not modified by encoding
void Decode(Decoder& d); // This actually resets the image content
private:
friend class Processing;
size_t mHeight;
size_t mWidth;
std::vector<Pixel> mPixels; // 2D array of Pixels
};
class Processing
{
public:
void apply(Image& image)
{
this->applyImpl(image.mHeight, image.mWidth, image.mPixels);
}
private:
virtual void applyImpl(size_t h, size_t w, std::vector<Pixel>& pixels) = 0;
};
Encoder and Decoder follow the same principle.
Note how I never needed an explicit pointer, and the guaranteed correctness that results from it.
First off, based on your provided code there are no ReadImage() & WriteImage() functions in the TImageProcessingEngine class, so the later code where you use such functionality is flawed.
As for the solution, you can make a getter function for the tImageMatrix pointer like this:
tImageMatrix* GetImageMatrix() { return mpImageMatrix; }
Then just pass that pointer (or a pointer to the whole TImage instance) to the TProcessing function you want to call.
Why you want to have a separate TProcessing process, when it specifically has functions just accessing mpImageMatrix;
In OOP, you have to bind the data members and it's operations..
So, IMO, remove your TProcessing class and have both the functions within TImage..
Your TImage will be like,
class TImage
{
public:
int ReadImage();
int WriteImage();
int ConvertToBinary();
int ConvertToGrayScale();
private:
//a two dimensional array holding the pixel values
tImageMatrix* mpImageMatrix;
};
You could create an accessor TImage class:
byte * pixelAt(unsigned x, unsigned y);