Qt prevod pole na PPM pixmap – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Qt prevod pole na PPM pixmap – C / C++ – Fórum – Programujte.comQt prevod pole na PPM pixmap – C / C++ – Fórum – Programujte.com

 

peter
~ Anonymní uživatel
4016 příspěvků
13. 1. 2016   #1
-
0
-

Mam funkci, ktera mi obrazek vrati jako

uint8 *pImage;

Jestli to spravne chapu, tak je to nejake pole s uint8 hodnotami. RGB za sebou, protoze tam je jeste jakasi konverzni funkce (kterou nepouzivam, nepotrebuji), ktera cte data jako (y * width + x) * components.
Potreboval bych to prevest na PPM pixmapu, kterou zobrazuji napriklad jako

QString path1 = "C:\\QT-projekty\\test-proj-j\\jpgcode\\smiley.jpg";
QPixmap pixmap(path1);
ui->label->setPixmap(pixmap);

Pixmapu je tez mozne nacist pomoci 

QByteArray z;
pixmap.loadFromData(z);

pixmapa je prave ve formatu PNM, ktery by melo byt snadne z toho pImage typu RGB dostat. PPM vypada tak, ze k RGB se na zacatek pripoji text 

P6
200 200
255

P asi oznacuje PPM, 6 je pocet komponent, obvykle 6, pro grayscale 5, ale asi by tam slo pouzit i 3.
Pak je sirka vyska obrazku.
255 na konci.

Ted bych potreboval tento spojit retezec + pImage do neceho, treba pImage2 a zkonvertovat to na format pixmap, abych to mohl vykreslit na obrazovku a videt, ze ta funkce generujici pImage skutecne udela obrazek.
Problem je, ze jako zacatecnik se uz snazim druhej den poskladat nejak ten string v QT a prevod formatu se mi uz nedari vubec. To Qt cpp funguje fakt nejak divne. Bud mi to pise errory, coz nejak opravim, a nebo mi pri spusteni aplikace aplikace hapne a nenapise proc. Takze pak nechapu, co se deje.
Pomohl by mi nekdo napsat tu jednoduchou prevodni funkci? Nektere veci se mi asi podarilo vyresit, ale neumim to propojit.

--- to jsou jakesi fragmenty kodu, jak asi by to mohlo vypadat
--- ake proste nechapu, jak s tim to cesko pracuje, jak pridat na zacatek pole typu uint8 nejaky Qstring;
        char result[]="";

        int c;
        int w;
        int h;
        c = decoder.IsColor() ? 6 : 5;
        w = decoder.GetWidth();
        h = decoder.GetHeight();
        //result = "P"+((char*)c)+"\n"+((char*)w)+" "+((char*)h)+"\n255\n";
        strcpy(result,"");
        strcat(result,"P");
        strcat(result,QString::number(c).toLocal8Bit());
        strcat(result,"\n");
        strcat(result,QString::number(w).toLocal8Bit());
        strcat(result," ");
        strcat(result,QString::number(h).toLocal8Bit());
        strcat(result,"\n255\n");
        strcat(result,QString::number(decoder.GetImageSize()).toLocal8Bit());
---
    uchar image2[] = "";
    uchar *pImage2 = image2;
    //image2[] = "";
    //pImage2 = &image2;

    //pImage2 = image1;

    int pos,z,x,y;
    z = 0;
    for (y = 0; y < height; ++y)
    {

       for (x = 0; x < width; ++x)
       {
             pos =  z * comps;
             ++z;
//             pImage +=pos;
             //pImage2+=pos;
             //pImage2[0] = (uchar)pImage[0];
             //pImage2[1] = (uchar)pImage[1];
             //pImage2[2] = (uchar)pImage[2];
       }
    }
--- tohle je original funkce, ktera s tim "pImage" pracuje jako
--- "const uint8 *pSrc", ale konvertuje to do "int a[3];" (to je to "int* pDst")
static void get_pixel(int* pDst, const uint8 *pSrc, int luma_only, int num_comps)
{
   int r, g, b;
   if (num_comps == 1)
   {
      r = g = b = pSrc[0];
   }
   else if (luma_only)
   {
      const int YR = 19595, YG = 38470, YB = 7471;
      r = g = b = (pSrc[0] * YR + pSrc[1] * YG + pSrc[2] * YB + 32768) / 65536;
   }
   else
   {
      r = pSrc[0]; g = pSrc[1]; b = pSrc[2];
   }
   pDst[0] = r; pDst[1] = g; pDst[2] = b;
}
Nahlásit jako SPAM
IP: 2001:718:2601:26c:e446:95...–
peter
~ Anonymní uživatel
4016 příspěvků
13. 1. 2016   #2
-
0
-

 To je ta druha funkce, ktera pouziva prave tu get_pixel. Radeji to sem dam, aby bylo jasnejsi, jak jsou ulozena data v tom obrazku. Pocet comps=3. Takze to nacita data, podle mne, jako RGBRGB... (0,3,6,... az do sirka*vyska orbrazku). Ale mozna, ze to chapu spatne :)

// Compute image error metrics.
static void image_compare(image_compare_results *pResults, int width, int height, const uint8 *pComp_image, int comp_image_comps, const uint8 *pUncomp_image_data, int uncomp_comps, int luma_only)
{
   double hist[256];
   double sum = 0.0f, sum2 = 0.0f;
   double total_values;
   const uint first_channel = 0, num_channels = 3;
   int x, y;
   uint i;

   memset(hist, 0, sizeof(hist));
   
   for (y = 0; y < height; y++)
   {
      for (x = 0; x < width; x++)
      {
         uint c;
         int a[3]; 
         int b[3]; 

         get_pixel(a, pComp_image + (y * width + x) * comp_image_comps, luma_only, comp_image_comps);
         get_pixel(b, pUncomp_image_data + (y * width + x) * uncomp_comps, luma_only, uncomp_comps);

         for (c = 0; c < num_channels; c++)
            hist[labs(a[first_channel + c] - b[first_channel + c])]++;
      }
   }

   pResults->max_err = 0;
   
   for (i = 0; i < 256; i++)
   {
      double x;
      if (!hist[i])
         continue;
      if (i > pResults->max_err)
         pResults->max_err = i;
      x = i * hist[i];
      sum += x;
      sum2 += i * x;
   }

   // See http://bmrc.berkeley.edu/…nt/psnr.html
   total_values = width * height;

   pResults->mean = sum / total_values;
   pResults->mean_squared = sum2 / total_values;

   pResults->root_mean_squared = sqrt(pResults->mean_squared);

   if (!pResults->root_mean_squared)
      pResults->peak_snr = 1e+10f;
   else
      pResults->peak_snr = log10(255.0f / pResults->root_mean_squared) * 20.0f;
}
Nahlásit jako SPAM
IP: 2001:718:2601:26c:e446:95...–
q
~ Anonymní uživatel
219 příspěvků
13. 1. 2016   #3
-
0
-

Před to pole to nedáš, musel bys vytvořit nové větší a do něj pak vložit tu hlavičku a data. Nebo to nabušit primitivně jako getpixel ze zdroje, setpixel do pixmapy.

Ale podle dokumentace by mělo jít vytvořit QImage přímo z těch dat. Pokud to teda je řada RGB, tak nějak takhle?

QImage img(pImage, sirka, vyska, QImage::Format_RGB888);
QPixmap pix = QPixmap::fromImage(img);
Nahlásit jako SPAM
IP: 78.156.159.–
peter
~ Anonymní uživatel
4016 příspěvků
14. 1. 2016   #4
-
0
-

   

    QImage img(pImage, width, height, QImage::Format_RGB888);
    QPixmap pixmap = QPixmap::fromImage(img);
    ui->label->setPixmap(pixmap);

 Jeee, parada, funguje to. A ja se drbu 3 dny s tim, ze tak jednoducha vec, co bych mel v js za 5 min je v cpp takova drbacka. Implementoval jsem jakousi nanojpeg knihovnu na nacitani jpeg a chci merit cas a menit kod. Mam par napadu, jak nacitani jpegu rozhodit na vic cpu, ale nejdriv jsem potreboval, at mi to funguje. Mozna to ale pozdeji stejne budu muset nejak prepsat, protoze to mozna zkusim pres GPU. Ale to jsou spis sny, pokud se mi podari probit vlastni upravou :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:78e3:ae...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 44 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý