rgb i hsv

0

Prosiłbym o wytlumaczenie nie ktorych rzeczy z konwertera rgb hsv
przesuwanie slidera do gory i w dol (0-255)

int position = ui->verticalSlider->value();

mam np 3 przyciski R G B
i np dla R mam

int i, j;
    unsigned char *ptr;

    ptr = img->bits();

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){
            ptr[szer*4*j + 4*i]= i/3;
            ptr[szer*4*j + 4*i + 1] = j/3;
            ptr[szer*4*j + 4*i + 2] = position;
        }
    }

skad wzięły się te i/3 , j/3 i na koniec position ?

mam jeszcze konwertek hsv

void MyWindow::konwertujHSV(int i, int j, int position)
{
    double C, X, H, m;
    C = ((double)i/(double)szer) * ((double)j/(double)wys);


    H = (double)position/60.0;


    X = C*(1-abs(fmod(H, 2.0)-1));

    if(H>=0 && H<=1){
        kolorR = C;
        kolorG = X;
        kolorB = 0;
    }
    else if(H<=2){
        kolorR = X;
        kolorG = C;
        kolorB = 0;
    }
    else if(H<=3){
        kolorR = 0;
        kolorG = C;
        kolorB = X;
    }
    else if(H<=4){
        kolorR = 0;
        kolorG = X;
        kolorB = C;
    }
    else if(H<=5){
        kolorR = X;
        kolorG = 0;
        kolorB = C;
    }
    else if(H<=6){
        kolorR = C;
        kolorG = 0;
        kolorB = X;
    }
    else{
        kolorR = 0;
        kolorG = 0;
        kolorB = 0;
    }

    m = (double)j/(double)wys - C;

    kolorR = 255*(kolorR + m);
    kolorG = 255*(kolorG + m);
    kolorB = 255*(kolorB + m);

}

Skąd wzieł się takie warunki? I np gdy majac przyciski H S V, przesuwam slidera do V skad wzięły się takie wartości " konwertujHSV(i, position765/100, j360/765);"?

void MyWindow::on_verticalSlider_4_sliderPressed()
{
    int position = ui->verticalSlider_4->value();


    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(i, position*765/100, j*360/765);
            zapalPiksel(i, j);

        }
    }
    update();
}

0

tak w skrócie. Jest to dziwny kod jak na sam konwerter RGB <-> HSV.
Te i/3 i j/3 faktycznie dziwne zważywszy, że są to dzielenia całkowitoliczbowe. Ponadto zmienna position w ogóle nie wiadomo skąd się wzięła i czym jest.
Ponadto pętla for nie powinna przypadkiem wyglądać tak (zamiana miejscami i i j wewnątrz ptr):

for(i=0; i<wys; i++){
    for(j=0; j<szer; j++){
        ptr[szer*4*i + 4*j]= i/3;
        ptr[szer*4*i + 4*j + 1] = j/3;
        ptr[szer*4*i + 4*j + 2] = position;
    }
}

Tu masz czysty i prosty do implementacji pseudokod zamiany w jedną jak i w druga stronę. Spróbuj sam napisać kod korzystając z niego.
https://www.rapidtables.com/convert/color/rgb-to-hsv.html
https://www.rapidtables.com/convert/color/hsv-to-rgb.html

--- Edit: ---
To nie jest zwykły konwerter jak tak się na to patrzy. On robi coś z kolorami pikseli w zależności od tego gdzie się znajdują. Napisz konkretnie co ma robić ten program, bo na 100% nie jest to konwersja RGB <-> HSV.

0

Cały kod wyglada tak

#include "mywindow.h"
#include "ui_mywindow.h"
#include <QDebug>

MyWindow::MyWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MyWindow)
{
    ui->setupUi(this);

    szer = ui->rysujFrame->width();
    wys = ui->rysujFrame->height();
    poczX = ui->rysujFrame->x();
    poczY = ui->rysujFrame->y();

    img = new QImage(szer,wys,QImage::Format_RGB32);
    img_cpy = new QImage(szer,wys,QImage::Format_RGB32);

    zamalujPoczatkowo();
    opcja=0;

}

MyWindow::~MyWindow()
{
    delete ui;
}

void MyWindow::on_exitButton_clicked()
{
    qApp->quit();
}

void MyWindow::paintEvent(QPaintEvent*)
{
    QPainter p(this);

    p.drawImage(poczX,poczY,*img);
}

void MyWindow::czysc()
{
    unsigned char *ptr;

    ptr = img->bits();

    int i,j;

    for(i=0; i<wys; i++)
    {
        for(j=0; j<szer; j++)
        {
            ptr[szer*4*i + 4*j] = 0;
            ptr[szer*4*i + 4*j + 1] = 0;
            ptr[szer*4*i + 4*j + 2] = 0;
        }
    }
}

void MyWindow::zapalPiksel(int x, int y)
{
    unsigned char *ptr;
    ptr = img->bits();

    if(x>=0 && y>=0 && x<szer && y<wys){
        ptr[szer*4*y + 4*x]= (int)kolorB;
        ptr[szer*4*y + 4*x + 1] = (int)kolorG;
        ptr[szer*4*y + 4*x + 2] = (int)kolorR;
    }

}


void MyWindow::on_red_clicked()
{
    opcja=0;
    zamalujCzerwono(0);
    ui->verticalSlider->setValue(0);
    ui->label_2->setNum(0);
}

void MyWindow::on_green_clicked()
{
    opcja=1;
    zamalujZielono(0);
    ui->verticalSlider->setValue(0);
    ui->label_2->setNum(0);
}

void MyWindow::on_blue_clicked()
{
    opcja=2;
    zamalujNiebiesko(0);
    ui->verticalSlider->setValue(0);
    ui->label_2->setNum(0);

}



void MyWindow::on_verticalSlider_sliderMoved(int position)
{
    ui->label_2->setNum(position);

    if(opcja == 0){
        zamalujCzerwono(position);
    }
    else if(opcja == 1){
        zamalujZielono(position);
    }
    else if(opcja == 2){
        zamalujNiebiesko(position);
    }

}

void MyWindow::zamalujPoczatkowo()
{
    int i, j;
    unsigned char *ptr;

    ptr = img->bits();

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){
            ptr[szer*4*j + 4*i]= i/3;
            ptr[szer*4*j + 4*i + 1] = j/3;
            ptr[szer*4*j + 4*i + 2] = 0;
        }
    }
    update();
}

void MyWindow::zamalujCzerwono(int position)
{
    int i, j;
    unsigned char *ptr;

    ptr = img->bits();

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){
            ptr[szer*4*j + 4*i]= i/3;
            ptr[szer*4*j + 4*i + 1] = j/3;
            ptr[szer*4*j + 4*i + 2] = position;
        }
    }
    update();
}

void MyWindow::zamalujZielono(int position)
{
    int i, j;
    unsigned char *ptr;

    ptr = img->bits();

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){
            ptr[szer*4*j + 4*i]= i/3;
            ptr[szer*4*j + 4*i + 1] = position;
            ptr[szer*4*j + 4*i + 2] = j/3;
        }
    }
    update();
}

void MyWindow::zamalujNiebiesko(int position)
{
    int i, j;
    unsigned char *ptr;

    ptr = img->bits();

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){
            ptr[szer*4*j + 4*i]= position;
            ptr[szer*4*j + 4*i + 1] = i/3;
            ptr[szer*4*j + 4*i + 2] = j/3;
        }
    }
    update();
}

void MyWindow::konwertujHSV(int i, int j, int position)
{
    double C, X, H, m;
    C = ((double)i/(double)szer) * ((double)j/(double)wys);


    H = (double)position/60.0;


    X = C*(1-abs(fmod(H, 2.0)-1));

    if(H>=0 && H<=1){
        kolorR = C;
        kolorG = X;
        kolorB = 0;
    }
    else if(H<=2){
        kolorR = X;
        kolorG = C;
        kolorB = 0;
    }
    else if(H<=3){
        kolorR = 0;
        kolorG = C;
        kolorB = X;
    }
    else if(H<=4){
        kolorR = 0;
        kolorG = X;
        kolorB = C;
    }
    else if(H<=5){
        kolorR = X;
        kolorG = 0;
        kolorB = C;
    }
    else if(H<=6){
        kolorR = C;
        kolorG = 0;
        kolorB = X;
    }
    else{
        kolorR = 0;
        kolorG = 0;
        kolorB = 0;
    }

    m = (double)j/(double)wys - C;

    kolorR = 255*(kolorR + m);
    kolorG = 255*(kolorG + m);
    kolorB = 255*(kolorB + m);

}

void MyWindow::on_verticalSlider_2_sliderMoved(int position)
{
    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(i, j, position);
            zapalPiksel(i, j);

        }
    }
    update();



}

void MyWindow::on_verticalSlider_3_sliderMoved(int position)
{
    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(position*765/100, i, j*360/765);
            zapalPiksel(i, j);

        }
    }
    update();
}

void MyWindow::on_verticalSlider_4_sliderMoved(int position)
{

    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(i, position*765/100, j*360/765);
            zapalPiksel(i, j);

        }
    }
    update();
}


void MyWindow::on_verticalSlider_2_sliderPressed()
{
    int i, j, position = ui->verticalSlider_2->value();
    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(j, i, position);
            zapalPiksel(i, j);

        }
    }
    update();
}

void MyWindow::on_verticalSlider_sliderPressed()
{
    int position = ui->verticalSlider->value();
    qDebug()<<position;

    if(opcja == 0){
        zamalujCzerwono(position);
    }
    else if(opcja == 1){
        zamalujZielono(position);
    }
    else if(opcja == 2){
        zamalujNiebiesko(position);
    }
}

void MyWindow::on_verticalSlider_3_sliderPressed()
{
    int position = ui->verticalSlider_3->value();

    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(position*765/100, i, j*360/765);
            zapalPiksel(i, j);

        }
    }
    update();
}

void MyWindow::on_verticalSlider_4_sliderPressed()
{
    int position = ui->verticalSlider_4->value();


    int i, j;

    for(i=0; i<wys; i++){
        for(j=0; j<szer; j++){

            konwertujHSV(i, position*765/100, j*360/765);
            zapalPiksel(i, j);

        }
    }
    update();
}

<img src=https://naforum.zapodaj.net/thumbs/a0db777abd8a.png alt=hosting zdjęć zapodaj.net />

0

Nie wiadomo skąd się wzięło /3, bo autor nie miał pojęcia o Magic Numbers.
Przypuszczalnie wartość ta została dobrana doświadczalnie zamiast zostać obliczona.
Prawdopodobnie miało być tak:

const double MaxColorValue = 255;
double redColumnRatio = MaxColorValue / (wys - 1);
...
    ptr[szer*4*i + 4*j]= qRound(redColumnRatio * i);

// albo jeśli ktoś się boi liczb zmiennoprzecinkowych:
const int MaxColorValue = 255;
...
    ptr[szer*4*i + 4*j]= (MaxColorValue * i + wys/2) / (wys - 1);

Tak samo nie wiem po co autor sam robi przeliczenia skoro Qt dostarcza konwersję miedzy różnymi formatami kolorów: https://doc.qt.io/qt-5/qcolor.html

Wniosek prosty raczej nie ufaj temu autorowi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1