Results 1 to 12 of 12

Thread: can't reuse a pure c++ .h file's methods and classes

  1. #1
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default can't reuse a pure c++ .h file's methods and classes

    hello I have this .h file and I want to use the RGBImage class defined in it: It's called image.h. I can use it under a cygwin cygnus compiler.

    Qt Code:
    1. #ifndef IMAGE_H
    2. #define IMAGE_H
    3.  
    4. #include <iostream.h>
    5.  
    6. template <class T> // an image of type T
    7. // use only simple types like int, unsigned char
    8. // double or float, etc.
    9. class Image {
    10.  
    11. private:
    12. T* pixel;
    13. int mHeight;
    14. int mWidth;
    15.  
    16. public:
    17. Image() { pixel = new T[1]; mHeight = mWidth = 0; }
    18. Image(const Image<T> & img );
    19. Image(int w, int h);
    20.  
    21. Image<T> & operator=(const Image<T> & img); // copy constructor
    22.  
    23. // OLD element access operator
    24. inline T & operator () (int x, int y) const {
    25. #ifdef IMAGE_RANGE_CHECK
    26. // cout << "Test range check..." << endl;
    27. if (y >= mHeight || x >= mWidth || y < 0 || x < 0) {
    28. cout << "Cannot access pixel (" << x << "," << y <<
    29. ") of Image[" << mWidth << " x " << mHeight << "]!" << endl;
    30. exit(1);
    31. }
    32. #endif
    33. return pixel[y * mWidth + x];
    34. }
    35.  
    36. // one-dimensional element access operator;
    37. inline T & operator [] (int i) const {
    38. #ifdef IMAGE_RANGE_CHECK
    39. if (i >= mWidth * mHeight || i < 0) {
    40. cout << "Cannot access pixel [" << i <<
    41. "] of Image[" << mWidth * mHeight << "]!" << endl;
    42. exit(1);
    43. }
    44. #endif
    45. return pixel[i];
    46. }
    47.  
    48. // destructor
    49. ~Image(){ delete [] pixel; }
    50.  
    51. void resize(int w, int h);
    52. void setAll( T x ); // set the values
    53.  
    54. inline int height() const { return mHeight; }
    55. inline int width() const { return mWidth; }
    56. T max();
    57. T min();
    58. };
    59.  
    60.  
    61. // --------------------------------------------------------------------
    62.  
    63. template <class T>
    64. Image<T>::Image( const Image<T> & img ) { // important for functions returning Image
    65. int h = img.height(), w = img.width(), i;
    66. pixel = new T[1];
    67. resize( w,h );
    68. for (i = 0; i < w*h; i++) pixel[i] = img[i];
    69. // for a faster alternative, replace previous line with the one below ;
    70. // and... you must #include <string.h>
    71. // memcpy( pixel, & img[0], sizeof(T) * w * h );
    72. }
    73.  
    74.  
    75. // set the image size only
    76. template <class T>
    77. Image<T>::Image( int w, int h ) {
    78. pixel = new T[1];
    79. resize( w,h );
    80. }
    81.  
    82.  
    83. // ---------------- Copy constructor -----------------------------------
    84. template <class T>
    85. Image<T> & Image<T>::operator=(const Image<T> & img) {
    86. int w,h,i;
    87. if ( this != &img ) { // don't copy to yourself
    88. resize( w = img.width(), h = img.height() );
    89. for (i = 0; i < w*h; i++) pixel[i] = img[i];
    90. // for a faster alternative, replace previous line with the one below ;
    91. // and... you must #include <string.h>
    92. // memcpy( pixel, & Img[0] , sizeof(T) * ht * wd );
    93. }
    94. return *this;
    95. }
    96.  
    97.  
    98. //----------- Allocates memory for an image, no initialization -----------
    99. template <class T>
    100. void Image<T>::resize(int w, int h) {
    101. int i;
    102. delete [] pixel;
    103.  
    104. if (w * h == 0) {
    105. cout << "CreateImage: invalid dimensions (" << w << " x " <<
    106. h << ")..." << endl;
    107. exit(1);
    108. }
    109.  
    110. pixel = new T[w*h];
    111. mWidth = w; mHeight = h;
    112. }
    113.  
    114.  
    115. // set the values of an image
    116. template <class T>
    117. void Image<T>::setAll( T x ) {
    118. int n = width() * height();
    119. for (int i = 0; i < n; i++) pixel[i] = x;
    120. }
    121.  
    122. // return the maximum value of the image
    123. template <class T>
    124. T Image<T>::max() {
    125. int i,imax,n = height()*width();
    126. for (i=imax=0; i < n; i++)
    127. if (pixel[i] > pixel[imax])
    128. imax = i;
    129. return pixel[imax];
    130. }
    131.  
    132. // return the minimum value of the image
    133. template <class T>
    134. T Image<T>::min() {
    135. int i,imin,n = height()*width();
    136. for (i=imin=0; i < n; i++)
    137. if (pixel[i] < pixel[imin])
    138. imin = i;
    139. return pixel[imin];
    140. }
    141.  
    142.  
    143.  
    144. #define RED(pixel) ((pixel) & 0xff)
    145. #define GREEN(pixel) (((pixel)>>8) & 0xff)
    146. #define BLUE(pixel) (((pixel)>>16) & 0xff)
    147. #define COLOR_RGB(r,g,b) (((b)<<16)+((g)<<8)+(r))
    148.  
    149.  
    150.  
    151. class RGBImage : public Image<int> {
    152.  
    153. public:
    154. RGBImage() { };
    155. ~RGBImage() { };
    156. inline void setPix( int x, int y, unsigned char r, unsigned char g, unsigned char b) {
    157. (*this)(x,y) = COLOR_RGB(r,g,b);
    158. }
    159. inline void setPix( int i, unsigned char r, unsigned char g, unsigned char b) {
    160. (*this)[i] = COLOR_RGB(r,g,b);
    161. }
    162. };
    163.  
    164.  
    165.  
    166.  
    167. #endif
    To copy to clipboard, switch view to plain text mode 

    Anybody can teach me specific steps to follow in order for me to use a fully-c++ .h file?
    Image Analysis Development Framework Using Qt (IADFUQ)

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Well, what you have there is a template image class and a particular Image<int>.
    I really haven't seen RGB components represented on 32 bits, so I recommend using 8 bit components.

    The class seems to have simple methods to get/set pixel data in an image, also to query image properties.

    What you have to do is to include this header in a source file( wherever you need it ) and instantiate the Image<int> class.
    Then you can fill this with image data.

    Basically, this is it.

    Regards

  3. The following user says thank you to marcel for this useful post:

    sincnarf (4th October 2007)

  4. #3
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Continued: Problems on image's colors after using qRed qBlue qGreen qRgb.

    Anyone here encountered loading an image (either of the three: JPEG PNG BMP) and all you see are shades of blue and black?

    Thanks by the way, but I have another problem. eventhough I can now compile my project without errors (eventhough I am able to use the functions COLOR_RGB(), RED(x,y),

    GREEN(x,y) and BLUE(x,y)), there seems to be something wrong with the qRgb, qRed, qGreen and qBlue functions of Qt. Or is it just that I am using the wrong

    image conversion type? - (QImage::Format_RGB32)

    I am trying to copy a QImage's RGB values to my Image<t,t> but wrong colors or RGB components are set regardless of the image type (JPG PNG BMP) using my function.

    Qt Code:
    1. void MainWindow::doF1()
    2. {
    3. QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), QDir::currentPath());
    4. if (!fileName.isEmpty()) {
    5. QImage tempImage(fileName);
    6. if (tempImage.isNull()) {
    7. QMessageBox::information(this, tr("Load Warning"), tr("Cannot load %1.").arg(fileName));
    8. return;
    9. }
    10.  
    11.  
    12. QImage image = tempImage.convertToFormat(QImage::Format_RGB32);
    13. imagelabImage.resize(image.width(), image.height());
    14. int pixel = 0;
    15. int x = 0;
    16. int y = 0;
    17.  
    18. for (x= 0; x < image.width(); x++){
    19. for (y = 0; y < image.height(); y++){
    20. pixel = image.pixel(x, y);
    21.  
    22. // The following line I think is where something weird happens to the
    23. // red and green components of a non-black pixel.
    24.  
    25. imagelabImage(x, y) = qRgb(qRed(pixel), qGreen(pixel) , qBlue(pixel));
    26.  
    27. // for Non-black colors (not (0, 0, 0)), the red and green components become 0 after applying qRgb().
    28.  
    29. // I used this to print each pixel
    30. // QString rgb = QString::number(qRed(pixel), 10) + QString::number(qGreen(pixel), 10) + QString::number(qBlue(pixel), 10);
    31. // QMessageBox::information(this, tr("rgb = "), rgb);
    32.  
    33. // and I observed that the color white becomes (0, 0, 255) which is not //correct, because white is supposed
    34. // to be (255, 255, 255) but I got (0, 0, 255) which is blue.
    35.  
    36. pixel = imagelabImage(x, y);
    37. image.setPixel(x, y, pixel);
    38. }
    39. }
    40.  
    41. QGraphicsPixmapItem *item = scene->addPixmap(QPixmap::fromImage(image));
    42. item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
    43. item->setFlag(QGraphicsItem::ItemIsMovable);
    44. graphicsViewVis->setScene(scene);
    45. graphicsViewVis->show();
    46. }
    47. }
    To copy to clipboard, switch view to plain text mode 

    The doF1 function stated above just copies a qt image with type QImage::Format_RGB32 into the RGBImage/Image<t,t> I originally included before. Then from that RGBImage / Image<t,t>, I copy it again to a QImage so that it can be displayed.

    See the screen shot below attached herewith. the left QGraphicsView is the original image, the right QGraphicsView contains the supposed to be copied image. but observe that the image is not copied correctly because you'll only see an image with shades of black and blue.



    Here is another image that when applied with my function doF1 becomes an image with only shades of blue and black.



    So my main problem now is I do not know what's wrong with my doF1 function, if it's the qRgb, qRed, qGreen, qBlue that have bugs or if I am using the wrong image conversion type (QImage::Format_RGB32).
    Attached Images Attached Images
    Attached Files Attached Files
    Image Analysis Development Framework Using Qt (IADFUQ)

  5. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    It seems to me that the RGBImage class stores RGB components as (unsigned char), while QImage gives them as int.

    So you have a type incompatibility there.

    What type is imagelabimage?

    Regards

  6. The following user says thank you to marcel for this useful post:

    sincnarf (4th October 2007)

  7. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Yes, I think that is it.
    Qt Code:
    1. #define COLOR_RGB(r,g,b) (((b)<<16)+((g)<<8)+(r))
    2.  
    3.  
    4.  
    5. class RGBImage : public Image<int> {
    6.  
    7. public:
    8. RGBImage() { };
    9. ~RGBImage() { };
    10. inline void setPix( int x, int y, unsigned char r, unsigned char g, unsigned char b) {
    11. (*this)(x,y) = COLOR_RGB(r,g,b);
    12. }
    13. inline void setPix( int i, unsigned char r, unsigned char g, unsigned char b) {
    14. (*this)[i] = COLOR_RGB(r,g,b);
    15. }
    16. };
    To copy to clipboard, switch view to plain text mode 
    If you look at that code, you can see that the pixel depth in that image is 24 bits, while a qRgb component is actually 32 bits and I don't really know if it works to assign a qRgb to a Image pixel.

    You could try something like this:
    Qt Code:
    1. unsigned char rcomp = (unsigned char)(qRed(pixel)>>24);
    2. unsigned char gcomp = (unsigned char)(qGreen(pixel)>>24);
    3. unsigned char bcomp = (unsigned char)(qBlue(pixel)>>24);
    4. imagelabImage->setPix(x, y, rcomp, gcomp, bcomp);
    To copy to clipboard, switch view to plain text mode 
    To retrieve the current pixel just ask getPix from imagelabImage.

    If shifting doesn't work, you can just try the explicit cast.
    I cannot test and I am not sure which one will work.

    You can take a look at what qRed,... return and if they are between 0..255 then only a cast is needed.
    I think this is the case so you can lose the shifting.

    Regards

  8. The following user says thank you to marcel for this useful post:

    sincnarf (4th October 2007)

  9. #6
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Thanks marchel, i did what was suggested but the images now do not look like shades of blue and black, instead, all the pixels were set to black!! (0, 0, 0). what exactly does >>24, >>8 or >>16 do?
    Image Analysis Development Framework Using Qt (IADFUQ)

  10. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    OK. I thought that would happen.
    ">>" is the C++ shift right operator.
    >> 24 means shift right with 24 bits aka divide by 2^24.

    But it is OK.
    You can just lose the shifting and it will work:
    Qt Code:
    1. unsigned char rcomp = (unsigned char)(qRed(pixel));
    2. unsigned char gcomp = (unsigned char)(qGreen(pixel));
    3. unsigned char bcomp = (unsigned char)(qBlue(pixel));
    4. imagelabImage->setPix(x, y, rcomp, gcomp, bcomp);
    To copy to clipboard, switch view to plain text mode 
    The shifting is not necessary anymore since qRed, qBlue and qGreen expand 8 bit values to 32 bit.
    So you basically get a 32 bit value with the most 24 significant bits always 0.

    Regards
    Last edited by marcel; 2nd August 2007 at 01:09.

  11. The following user says thank you to marcel for this useful post:

    sincnarf (4th October 2007)

  12. #8
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Still no luck removing the >>24 does not set the right colors, it returned to having shades of blue and black only.
    Image Analysis Development Framework Using Qt (IADFUQ)

  13. #9
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    I don't know. Can you post the updated code?
    It wouldn't hurt if you did some debugging, to see what values you actually put/take out from that image.

    Still no luck removing the >>24 does not set the right colors, it returned to having shades of blue and black only.
    Well, things like this (meaning image handling) can't be done by guessing to add or remove something in the code. What you do has to be logic.

    So I would start with debugging, see what are the pixels taken from the QImage and what are the pixels taken from the Image.

    If possible, post those debug values.

    Regards
    Last edited by marcel; 2nd August 2007 at 10:17.

  14. The following user says thank you to marcel for this useful post:

    sincnarf (2nd August 2007)

  15. #10
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Thanks again Marcel. Here's my current function and I can already load an image, though there's a problem with the colors (see attached image). The colors are somewhat "adjusted" using Format_RGB32. The original objective is just to create an exact copy from the left graphicsView to the rightgraphics view.

    Qt Code:
    1. void MainWindow::doF1()
    2. {
    3. QString fileName = QFileDialog::getOpenFileName(this,
    4. tr("Open Image"), QDir::currentPath());
    5. if (!fileName.isEmpty()) {
    6. QImage tempImage(fileName);
    7.  
    8. if (tempImage.isNull()) {
    9. QMessageBox::information(this, tr("Load Warning"),
    10. tr("Cannot load %1.").arg(fileName));
    11. return;
    12. }
    13. QImage image = tempImage.convertToFormat(QImage::Format_RGB32);
    14. RGBImage rgbImage;
    15. rgbImage.resize(image.width(), image.height());
    16.  
    17. int pixel = 0;
    18. int x = 0;
    19. int y = 0;
    20.  
    21. for (x= 0; x < image.width(); x++){
    22. for (y = 0; y < image.height(); y++){
    23. pixel = image.pixel(x, y);
    24.  
    25. unsigned char rcomp = (unsigned char)(qRed(pixel));
    26. unsigned char gcomp = (unsigned char)(qGreen(pixel));
    27. unsigned char bcomp = (unsigned char)(qBlue(pixel));
    28.  
    29. rgbImage.setPix(x, y, rcomp, gcomp, bcomp);
    30.  
    31. pixel = rgbImage(x,y);
    32. image.setPixel(x, y, pixel);
    33.  
    34. }
    35. }
    36.  
    37. QGraphicsPixmapItem *item = scene->addPixmap(QPixmap::fromImage(image));
    38. item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
    39. item->setFlag(QGraphicsItem::ItemIsMovable);
    40. graphicsViewVis->setScene(scene);
    41. graphicsViewVis->show();
    42. }
    43. }
    To copy to clipboard, switch view to plain text mode 

    Observe the colors that were set in the right image (attached Format_RGB32.jpg), I tried to print the values of the rgbImage and they're exactly the same as the original/left Image, I think that there's something wrong with using QImage::Format_RGB32.

    So I tried to use QImage::Indexed8 and the colors were correct , but the main problem in using QImage::Indexed8 is that the right image has white spots and the loading of the image takes too long (about 15 seconds, I thought the program hung but it didnt).

    Which makes me decide to use QImage::Format_RGB32 and possibly create a way to recompute/correct the rgb values. This is my current problem.
    Attached Images Attached Images
    Image Analysis Development Framework Using Qt (IADFUQ)

  16. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    You should stick to RGB32.
    The problem is in line 31 of the code you posted:
    Qt Code:
    1. pixel = rgbImage(x,y);
    To copy to clipboard, switch view to plain text mode 
    As before, you can't assign that directly.
    First convert it to qRgb, using qRed, etc...
    It is the reverse transformation of what you did before.

    EDIT: Actually, I think it is better to use the macros from your header to extract the components and build a qRgb:
    Qt Code:
    1. #define RED(pixel) ((pixel) & 0xff)
    2. #define GREEN(pixel) (((pixel)>>8) & 0xff)
    3. #define BLUE(pixel) (((pixel)>>16) & 0xff)
    To copy to clipboard, switch view to plain text mode 

    Regards

  17. The following user says thank you to marcel for this useful post:

    sincnarf (4th October 2007)

  18. #12
    Join Date
    Apr 2007
    Posts
    117
    Thanks
    84
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: can't reuse a pure c++ .h file's methods and classes

    Quote Originally Posted by marcel View Post
    EDIT: Actually, I think it is better to use the macros from your header to extract the components and build a qRgb:
    At last! Solved the problem. Thanks !!! Thank you Marcel, expect your name in my acknowledgements page. Hehe
    Image Analysis Development Framework Using Qt (IADFUQ)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.