Ir ao conteúdo
  • Cadastre-se

C Como otimizar uma função?


Cambalinho

Posts recomendados

@Cambalinho @Cambalinho    lógico que quanto menos comandos usar menos tempo a função vai gastar ,  então aproveite  ao máximo cada um deles ,por exemplo em um menu :

escreva("1 - adicionar\n")
escreva("2 - listar\n")
escreva("3 - sair ")
leia(opcao)

ai vai chamar a função "escreva" , 3 e vezes 

escreva
(
  "1 - adicionar\n",
  "2 - listar\n",
  "3 - sair  "
)

e nessa aqui chama a função apenas uma vez , assim vai bem mais rápido  .

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <vector>
#include <gdiplus.h>
#include <stdlib.h>
#include <algorithm>
#include <thread>
#include <future>
#include "image.h"

using namespace Gdiplus;
using namespace std;

/*const double PI = 3.14159265358979;

struct point
{
    float x,y,z;
} ;

struct angle
{
    float x,y,z;
} ;*/

point Convert3DTO2D(point Position, float FocalDistance=0.05)
{
    point Point2D;
    Point2D.x=Position.x * FocalDistance/Position.z;
    Point2D.y=Position.y*FocalDistance/Position.z;
    return Point2D;
}

angle ConvertDegreesToRadians(angle Rotation)
{

    double deg2Rad;
    deg2Rad = PI / 180;
    angle ConvertDegrees;
    ConvertDegrees.x = Rotation.x * deg2Rad;
    ConvertDegrees.y = Rotation.y * deg2Rad;
    ConvertDegrees.z = Rotation.z * deg2Rad;
    return ConvertDegrees;
}

point RotationPoints2(point Coordenate, const angle AngleCoordenate, const point pivot={0,0,0})
{
    angle radians= ConvertDegreesToRadians(AngleCoordenate);
    point RotatedPoint;
    RotatedPoint=Coordenate;
    Coordenate.x-=pivot.x;
    Coordenate.y-=pivot.y;
    Coordenate.z-=pivot.z;
    //First we rotate the Z:
    RotatedPoint.x=Coordenate.x * cos(AngleCoordenate.z)-Coordenate.y*sin(AngleCoordenate.z);
    RotatedPoint.y=Coordenate.x * sin(AngleCoordenate.z)+Coordenate.y*cos(AngleCoordenate.z);
    //RotatedPoint.z=Coordenate.z;

    //Second we rotate the Y:
    RotatedPoint.x=RotatedPoint.x * cos(AngleCoordenate.y)+RotatedPoint.z*sin(AngleCoordenate.y);
    //RotatedPoint.y=RotatedPoint.y;  // pointless self assignemnt
    RotatedPoint.z=-RotatedPoint.x * sin(AngleCoordenate.y)+RotatedPoint.z*cos(AngleCoordenate.y);

    //Third we rotate the X:
    //RotatedPoint.x=RotatedPoint.x;   // pointless self assignemnt
    RotatedPoint.y=RotatedPoint.y * cos(AngleCoordenate.x)-RotatedPoint.z*sin(AngleCoordenate.x);
    RotatedPoint.z=RotatedPoint.y * sin(AngleCoordenate.x)+RotatedPoint.z*cos(AngleCoordenate.x);

    RotatedPoint.x+=pivot.x;
    RotatedPoint.y+=pivot.y;
    RotatedPoint.z+=pivot.z;
    return RotatedPoint;
}

point RotationPoints(point pt, angle Angle, point pivot={0,0,0},point scale={1,1,1})
{
    angle radians= ConvertDegreesToRadians(Angle);
    Angle.x =radians.x;
    Angle.y =radians.y;
    Angle.z =radians.z;
    point p={pt.x-pivot.x,pt.y-pivot.y,pt.z-pivot.z};
    point rot,temp;
    temp={(p.y)*cos(Angle.x)+(-p.z)*sin(Angle.x),(p.z)*cos(Angle.x)+(p.y)*sin(Angle.x)};
    rot.y=temp.x;rot.z=temp.y;
    p.y = rot.y;p.z = rot.z;
    temp={(p.z)*cos(Angle.y)+(-p.x)*sin(Angle.y),(p.x)*cos(Angle.y)+(p.z)*sin(Angle.y)};
    rot.z=temp.x;rot.x=temp.y;
    p.x=rot.x;
    temp={(p.x)*cos(Angle.z)+(-p.y)*sin(Angle.z),(p.y)*cos(Angle.z)+(p.x)*sin(Angle.z)};
    rot.x=temp.x;rot.y=temp.y;
    return {(scale.x*rot.x+pivot.x),(scale.y*rot.y+pivot.y),(scale.z*rot.z+pivot.z)};
}

float GetLineLength(point p1,point p2)
{
	return sqrt( (p1.x-p2.x)* (p1.x-p2.x) + (p1.y-p2.y)* (p1.y-p2.y) + (p1.z-p2.z)* (p1.z-p2.z));
}

//Get Points Line:
point lineto(point fp,point p,float length)
{
	point res;
    float L=GetLineLength(fp,p);
    res.x=fp.x+length*(p.x-fp.x)/L;
    res.y=fp.y+length*(p.y-fp.y)/L;
    res.z=fp.z+length*(p.z-fp.z)/L;
    return res;
}
vector<point> GetPointsLine(point origin,point destination)
{
    point t=origin;
    vector<point> coordenates;
	float dst=GetLineLength(origin,destination);
	for (int i=0;i<=dst;i++)
    {
        t=lineto(t,destination,1);
        coordenates.push_back(t);
    }
    return coordenates;
}

point perspective(const point &p,const point &eyepoint)
{
    float   w=1+(p.z/eyepoint.z);
    return {(p.x-eyepoint.x)/w+eyepoint.x,
    (p.y-eyepoint.y)/w+eyepoint.y,
    (p.z-eyepoint.z)/w+eyepoint.z};
}

//Draw a Line:
void DrawLine(HDC WindowHDC,point origin,point destination,COLORREF color=RGB(0,0,255) )
{

    //for convert 3D to 2D we must:
    //have Focal Distance, in these case is 100
    //float FocalDistance =100;
    //2D.X = 3D.X * FocalDistance / 3D.Z
    //2D.Y = 3D.Y * FocalDistance / 3D.Z


    //Getting the Points of a line:
    vector<point> coordenates;

    //origin.z=-origin.z;
    //destination.z=-destination.z;
    coordenates = GetPointsLine(origin,destination);
    point eyepoint={250,150,300};
    //now we draw the line with a color and convert the 3D to 2D:
	for (point LinePoints:coordenates)
    {
    	point p=perspective(LinePoints,eyepoint);
    	//SetPixel(WindowHDC,p.x,p.y,color);

    	std::thread thread_obj(SetPixel, WindowHDC,p.x,p.y,color);
    	thread_obj.join();
    }
}

void DrawRectangle(HDC WindowHDC,point  Top, point Left, point Right, point Bottom,COLORREF color=RGB(255,0,0) )
{

    //for convert 3D to 2D we must:
    //have Focal Distance, in these case is 100
    //2D.X = 3D.X * FocalDistance / 3D.Z
    //2D.Y = 3D.Y * FocalDistance / 3D.Z
    float FocalDistance =100;

    //Getting the Points of a line:
    vector<point> coordenates;

/*    coordenates = GetPointsLine(origin,destination);
    point eyepoint={250,150,300};
    //now we draw the line with a color and convert the 3D to 2D:
	for (point LinePoints:coordenates)
    {
    	point p=Convert3DTO2D(LinePoints); //perspective(LinePoints,eyepoint);
    	SetPixel(WindowHDC,p.x,p.y,color);
    }*/
}

//Draw an Image:
void DrawImage(HDC HDCWindow,point corners[4], HDC HDCOrigin, int PosX, int PosY, int Width, int Height)
{

    POINT ImageCordeners[3];

    //Move Top-Left Corner:
    ImageCordeners[0].x=corners[0].x;
    ImageCordeners[0].y=corners[0].y;

    //Move Top-Right Corner:
    ImageCordeners[1].x=corners[1].x;
    ImageCordeners[1].y=corners[1].y;

    ////Move the  Bottom-Right Corner:
    ImageCordeners[2].x=corners[2].x;
    ImageCordeners[2].y=corners[2].y;

    PlgBlt(HDCWindow,ImageCordeners,HDCOrigin,PosX,PosY,Width,Height,NULL,0,0);
}

//Draw image pixel a pixel:
void DrawImagePoint(HDC HDCDestination,HDC HDCOrigin, point TopLeft,point TopRight,point BottomLeft,point BottomRight)
{
    //Getting the Points of a line:
    vector<point> LeftLine;
    LeftLine = GetPointsLine(TopLeft,BottomLeft);

    vector<point> RgihtLine;
    RgihtLine = GetPointsLine(TopRight,BottomRight);


    for(int PosX=0; PosX<LeftLine.size(); PosX++)
    {
        vector<point> PixelLine;
        PixelLine=GetPointsLine(LeftLine[PosX], RgihtLine[PosX]);

        for (int PosY=0; PosY<PixelLine.size(); PosY++)
        {
            point Point=PixelLine[PosY];

            COLORREF color;
            color=::GetPixel(HDCOrigin,PosY+800,PosX);
            ::SetPixel( HDCDestination,PosY,PosX,color);
        }
    }
}

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());
    point TopLeft={100, 200,0};
    point TopRight={200,200,0};
    point BottomLeft={100,300,0};
    point BottomRight={200,300,0};

    point RotationPoint={250,150,0};//center of rectangle
    angle angles;
    image img("c:\\test.jpg");
    img.DrawImage(WindowHDC,800,0);
    RECT a;

    a.left=0;
    a.right=800;
    a.top=0;
    a.bottom=800;
	do
    {
        //angles.x+=0.1;
        //TopLeft:
        point TopLeftRotated=TopLeft;//RotationPoints(TopLeft,{angles.x,angles.y,angles.z},RotationPoint);



        //TopRight:
        point TopRightRotated=TopRight;//RotationPoints(TopRight,{angles.x,angles.y,angles.z},RotationPoint);


        //BottomLeft:
        point BottomLeftRotated=BottomLeft;//RotationPoints(BottomLeft,{angles.x,angles.y,angles.z},RotationPoint);


        //BottomRight:
        point BottomRightRotated=BottomRight;//RotationPoints(BottomRight,{angles.x,angles.y,angles.z},RotationPoint);


        DrawImagePoint(WindowHDC,WindowHDC,TopLeftRotated,TopRightRotated,BottomLeftRotated, BottomRightRotated);


        Sleep(100);

        FillRect(WindowHDC,&a, CreateSolidBrush(RGB(0,0,0)));
    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));//press escape for exit
    cout<<"Press return to end . . ."<<endl;
    cin.get();
}

image.h:

#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <vector>
#include <gdiplus.h>
#include <stdlib.h>
#include <algorithm>
#include<thread>
/*void foo(param)
{
    // Do something
}

// The parameters to the function are put after the comma
std::thread thread_obj(foo, params);*/

using namespace Gdiplus;
using namespace std;

const double PI = 3.14159265358979;

struct point
{
    float x,y,z;
} ;

struct angle
{
    float x,y,z;
} ;


//Convert the std::string to std::wstring:
std::wstring towstring(const std::string& v)
{
    std::wstring out(v.size()+1,L'\0');

    int size = MultiByteToWideChar(CP_UTF8, 0, v.c_str(), -1, &out[0], out.size());

    out.resize(size-1);
    return out;
}

class line
{
    public:
        point OriginLine;
        point DestinationLine;

    line(point origin,point destination)
    {
        OriginLine=origin;
        DestinationLine=destination;
    }

    float GetLineLength(point p1,point p2)
    {
        return sqrt( (p1.x-p2.x)* (p1.x-p2.x) + (p1.y-p2.y)* (p1.y-p2.y) + (p1.z-p2.z)* (p1.z-p2.z));
    }

    //Get Points Line:
    point lineto(point fp,point p,float length)
    {
        point res;
        float L=GetLineLength(fp,p);
        res.x=fp.x+length*(p.x-fp.x)/L;
        res.y=fp.y+length*(p.y-fp.y)/L;
        res.z=fp.z+length*(p.z-fp.z)/L;
        return res;
    }

    point perspective(const point &p,const point &eyepoint={250,150,300})
    {
        float   w=1+(p.z/eyepoint.z);
        return {(p.x-eyepoint.x)/w+eyepoint.x,
        (p.y-eyepoint.y)/w+eyepoint.y,
        (p.z-eyepoint.z)/w+eyepoint.z};
    }

    vector<point> GetPointsLine()
    {
        point t=OriginLine;
        vector<point> coordenates;
        float dst=GetLineLength(OriginLine,DestinationLine);
        for (int i=0;i<=dst;i++)
        {
            t=lineto(t,DestinationLine,1);
            t=perspective(t);
            coordenates.push_back(t);
        }
        return coordenates;
    }
};

POINT Convert3DTo2D(point Dot, int FocalDistance=100)
{
    POINT ptDot;
    ptDot.x=Dot.x/Dot.z * FocalDistance;
    ptDot.y=Dot.y/Dot.z * FocalDistance;
}

class image
{
    public:

    ULONG_PTR m_gdiplusToken=NULL;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Graphics *graphic=nullptr;
    Gdiplus::Bitmap *img;
    HDC ImageHDC=NULL;
    int Width=0;
    int Height=0;

    void GetHDC(HDC &imgHDC)
    {
        imgHDC=graphic->GetHDC();
    }

    void ReleaseHDC(HDC &imgHDC)
    {
        graphic->ReleaseHDC(imgHDC);
    }

    COLORREF GetPixel(int PosX, int PosY)
    {
        Color clr;
        img->GetPixel(PosX, PosY, &clr);
        return  clr.ToCOLORREF();
    }

    void SetPixel(int PosX, int PosY, COLORREF color)
    {
        Color *clr;
        clr->SetFromCOLORREF(color);
        img->SetPixel(PosX, PosY,clr);
    }

    image()
    {
        //nothing:
    }

    image(int SizeWidth, int SizeHeight)
    {
        New(SizeWidth, SizeHeight);

    }

    image(string strFile)
    {
        FromFile(strFile);
    }

    void Clear(Color BackColor=Color::White)
    {
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);
    }

    void New(int Width, int Height,Color BackColor=Color::White)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img=new Gdiplus::Bitmap(Width, Height);
        graphic=new Gdiplus::Graphics(img);
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);
        delete Fill;
    }

    void Dispose()
    {
        //clear all objects for avoid memory leaks:
        if(m_gdiplusToken)
        {
            Gdiplus::GdiplusShutdown(m_gdiplusToken);
        }
        //by some reason, i can't delete the 'new' values: 'img' and 'graphic'
        //the program terminates with an exit error
    }

    ~image()
    {
        Dispose();
    }

    void FromFile(string strFile)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();
        graphic= Graphics::FromImage(this->img);
    }

    void DrawImage(HDC DestinationHDC, float PosX, float PosY)
    {
        if(!img || !m_gdiplusToken) return;
        Gdiplus::Graphics graphics2(DestinationHDC);
        graphics2.DrawImage(img , PosX, PosY, img->GetWidth(), img->GetHeight());
    }

    void DrawImage(Graphics *Destination, float PosX, float PosY)
    {
        if(!img || !m_gdiplusToken) return;
        Destination->DrawImage(img, PosX, PosY, img->GetWidth(), img->GetHeight());
    }


    //Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight, angle angles={0,0,0})
    {
        //Getting the Points of a line:
        vector<point> LeftLine;
        //TopLeft = RotationPoints(TopLeft,angles);
        //TopRight = RotationPoints(TopRight,angles);
        //BottomLeft = RotationPoints(BottomLeft,angles);
        //BottomRight = RotationPoints(BottomRight,angles);
        line LineLeft(TopLeft,BottomLeft);
        LeftLine = LineLeft.GetPointsLine();
        vector<point> RgihtLine;
        line LineRight(TopRight,BottomRight);
        RgihtLine=LineRight.GetPointsLine();


        for(int PosX=0; PosX<LeftLine.size(); PosX++)
        {
            vector<point> PixelLine;
            line LinePixel(LeftLine[PosX], RgihtLine[PosX]);
            PixelLine=LinePixel.GetPointsLine();

            for (int PosY=0; PosY<PixelLine.size(); PosY++)
            {
                point Point=PixelLine[PosY];
                Color color;
                img->GetPixel(PosY+800,PosX,&color);
                COLORREF clr =color.ToCOLORREF();
                ::SetPixel(hdcDestination,PosY,PosX,clr);
            }
        }
    }
};

 

este codigo faz o que preciso: desenha 1 imagem pixel a pixel... mas preciso de velocidade... então queria ver como posso ganhar mais velocidade... nem 1 frame por segundo consigo e é só 1 imagem... imagine várias 😞

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

voltando um pouco atrás: o problema está mesmo no SetPixel() e GetPixel() ou também na divisão GetPointsLine()?
eu sei que o SetPixel() e GetPixel() são lentos... se calhar tenho mesmo de usar DIB's. mas mesmo assim gostava de saber onde está a consumo maximo do tempo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho Eu cheguei a escrever um código como esse aí, chamar SetPixel() milhares de vezes não é a melhor escolha... Veja, uma imagem 250x250, relativamente pequena, sendo construída pixel a pixel:

1.gif.63afefbb55fc92e577ec9074fde9a6d3.gif

São ao todo 62500 chamadas de SetPixel(). Por isso eu disse:

Em 15/02/2022 às 20:04, Lucca Rodrigues disse:

Em vez de chamar SetPixel() centenas/milhares de vezes, tenha um HBITMAP carregado em mãos e chame CreateWindowW().

Uma ideia que posso te dar é criar um vetor com o valor RGB de cada pixel, e então chamar CreateBitmap().

unsigned int* pixels = (unsigned int*)malloc(bmWidth*bmHeight*sizeof(unsigned int));
// preencha o vetor...
CreateBitmap(bmWidth,bmHeight,1,32,pixels);

Atribua o retorno da função à um HBITMAP e chame CreateWindowW()SendMessage() em sequência para criar na janela uma imagem estática.

Veja, se tratando de uma aplicação para Windows, chame essas funções na WndProc(). Você pode fazer isso através da mensagem WM_CREATE.

Dê uma olhada nesse link, nele tem um exemplo que expressa bem o que quero dizer.

A diferença? Veja:

2.gif.3734040e91d138ffe67eeedbda429dca.gif

De certa forma, a imagem aparece junto à janela pai 🙂

  • Obrigado 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho

3 horas atrás, Cambalinho disse:

você usou o ponteiro 'pixels'...

pixels é um vetor dinâmico, criado a partir das dimensões do bitmap: bmWidth e bmHeight.

 

3 horas atrás, Cambalinho disse:

pode mostrar o  loop para obter o RGB ou mesmo a cor(COLORREF)?

Você vai preencher o vetor no mesmo loop em que chama SetPixel().

O valor de COLORREF tem o formato hexadecimal 0x00bbggrr, os componentes de cor são armazenados na ordem oposta do RGB.

Essa macro inverte o azul e o vermelho, pode usar para converter de um para outro se precisar:

#define COLORREFxRGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                 | ((Color << 16) & 0xff0000)

 

3 horas atrás, Cambalinho disse:

você acha que o problema está aqui ou tenho de otimizar melhor as outras funções?

O problema mais evidente é SetPixel() ser chamada milhares de vezes, e como eu mostrei, não é eficiente.

Não vai ter problemas se criar uma janela com imagem estática a partir de um HBITMAP carregado.

Aliás, talvez esteja tentando criar a imagem no console, mas recomendo trabalhar com uma aplicação Windows. Aquele site que linkei tem um exemplo de como criar uma imagem estática, então acredito que basta rotacionar sua imagem como desejar e seguir o que eu tinha dito:

23 horas atrás, Lucca Rodrigues disse:

criar um vetor com o valor RGB de cada pixel, e então chamar CreateBitmap().

unsigned int* pixels = (unsigned int*)malloc(bmWidth*bmHeight*sizeof(unsigned int));
// preencha o vetor...
CreateBitmap(bmWidth,bmHeight,1,32,pixels);

Atribua o retorno da função à um HBITMAP e chame CreateWindowW()SendMessage() em sequência para criar na janela uma imagem estática.

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho

9 horas atrás, Cambalinho disse:

se eu precisar de um pixel especifico,  nesse loop, como posso obter o pixel usando x e y?

Talvez por meio das variáveis PosX e PosY, não li o código.

De modo geral, CreateDIBSection() te fornece um ponteiro para o local dos bits (pixels) do bitmap, é uma forma de ter acesso.

Por que precisaria disso nesse contexto?

 

12 minutos atrás, Cambalinho disse:

você utiliza um loop com step de 4 e:
- Red é +2;

- Green é +1;

- Blue é + 0;

- Alpha é +3.

certo?

Não sei se entendi do que está falando... 🤪

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Lucca Rodrigues

for(int PixelPosition=0; PixelPosition<PixelsCount; PixelPosition+=4)
{

     byte Red = PixelPosition[(PixelPositionY*ImageWidth+PixelPositionX) + 2]; // obtemos Red;
     byte Green = PixelPosition[(PixelPositionY*ImageWidth+PixelPositionX) + 1]; // obtemos Green;
     byte Blue = PixelPosition[(PixelPositionY*ImageWidth+PixelPositionX) + 0]; // obtemos Blue;
     byte Alpha = PixelPosition[(PixelPositionY*ImageWidth+PixelPositionX) + 3]; // obtemos Alpha;

}

está correcto?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho Novamente, não sei do que você está falando.

Eu recomendo que você sempre contextualize seu problema, poste o código completo e pergunte com clareza e objetividade, você não fez nenhuma dessas 3 coisas.

Já te expliquei como criar uma imagem estática na janela, o problema era esse, tentou corrigir?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

estou a tentar a fazer a actualização:

void New(int Width, int Height,Color BackColor=Color::White)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img=new Gdiplus::Bitmap(Width, Height);
        graphic=new Gdiplus::Graphics(img);
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);

        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        Color clr(0x00,0x00,0x00);
        HBITMAP hBitmap;
        Bitmap->GetHBITMAP(clr,&hBitmap);
        DIBSECTION dibs;
        ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
        ::GetDIBits(graphic->GetHDC(), hBitmap,0,0,&pixels,hBitmap,dibs.dsBmih.biClrUsed);
        delete Fill;
    }

na linha:

Bitmap->GetHBITMAP(clr,hBitmap);

tenho erros:
"error: expected unqualified-id before '->' token"

noutra linha tenho:
"error: cannot convert 'HBITMAP__**' to 'HBITMAP' {aka 'HBITMAP__*'}"

qual é o meu erro?

sim não notei 1 erro e ja resolvi:

era 'img' e não 'Bitmap'.

tinha mais1 erro, mas resolvi.

 

eis com leio 1 ficheiro de imagem:

void FromFile(string strFile)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();
        graphic= Graphics::FromImage(this->img);
        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        Color clr(0x00,0x00,0x00);
        HBITMAP *hBitmap;
        //Gdiplus::Bitmap *img;
        img->GetHBITMAP(clr,hBitmap);
        DIBSECTION dibs;
        ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
        BITMAPINFO bitinfo;
        ::GetObject(hBitmap, sizeof(BITMAPINFO), &bitinfo);
        ::GetDIBits(graphic->GetHDC(), *hBitmap,0,0,&pixels,&bitinfo,dibs.dsBmih.biClrUsed);
    }

 

o compilador não me dá erro... mas mesmo assim ao executar tenho este erro:

"Process returned -1073741819 (0xC0000005)   execution time : 0.830 s
Press any key to continue."

o que estou a fazer de errado com o codigo?
sim estou a combinar o GDIPLUS(para ler os ficheiros) e GDI para imprimir

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@Cambalinho

Você já tem a cor do pixel em questão antes de chamar a SetPixel().

Em vez de chamar a função, preencha o vetor, assim como eu tinha dito:

Em 17/02/2022 às 21:39, Lucca Rodrigues disse:

Você vai preencher o vetor no mesmo loop em que chama SetPixel().

Se foi você que escreveu o código, saberá modificar da forma adequada. A ideia é justamente armazenar o pixel em vez de pintá-lo na janela.

Você vai precisar do valor RGB dos pixels, e se tem COLORREF em mãos, converta:

Em 17/02/2022 às 21:39, Lucca Rodrigues disse:

Essa macro inverte o azul e o vermelho, pode usar para converter de um para outro se precisar:

#define COLORREFxRGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                 | ((Color << 16) & 0xff0000)

Coloque a macro na primeira linha do código e chame-a como função, seu retorno é o valor RGB.

No mais:

Em 16/02/2022 às 22:16, Lucca Rodrigues disse:

chamar CreateBitmap().

Atribua o retorno da função à um HBITMAP e chame CreateWindowW()SendMessage() em sequência para criar na janela uma imagem estática.

 

Seu código não vai mudar em geral, pode rotacionar e modificar o bitmap do jeito que quiser, o fato é que deveria ser uma aplicação Windows, que faz mais sentido do que uma aplicação de console nesse caso, já que está usando a API do Windows.

Veja o link de exemplo de como criar uma imagem estática na janela:

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void LoadMyImage(void);

HBITMAP hBitmap;

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow) {

    MSG  msg;    
    WNDCLASSW wc = {0};
    wc.lpszClassName = L"Static image";
    wc.hInstance     = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc   = WndProc;
    wc.hCursor       = LoadCursor(0,IDC_ARROW);

  
    RegisterClassW(&wc);
    CreateWindowW(wc.lpszClassName, L"Static image",
                  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  100, 100, 330, 270, 0, 0, hInstance, 0);

    while (GetMessage(&msg, NULL, 0, 0)) {
    
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam) {
    
    HWND hsti;

    switch(msg) {

        case WM_CREATE:
    
            LoadMyImage();
            hsti = CreateWindowW(L"Static", L"", 
                WS_CHILD | WS_VISIBLE | SS_BITMAP,
                5, 5, 300, 300, hwnd, (HMENU) 1, NULL, NULL);

            SendMessage(hsti, STM_SETIMAGE,
                (WPARAM) IMAGE_BITMAP, (LPARAM) hBitmap); 
            break;

        case WM_DESTROY:

            DeleteObject(hBitmap);
            PostQuitMessage(0);
            break;
    }

    return DefWindowProcW(hwnd, msg, wParam, lParam);
}

void LoadMyImage(void) {

    hBitmap = LoadImageW(NULL, L"C:\\prog\\slovakia.bmp", IMAGE_BITMAP,
        0, 0, LR_LOADFROMFILE);
}

No exemplo, o autor chama LoadImageW() pra carregar o bitmap, no nosso caso, CreateBitmap() faria esse serviço.

De resto, WinMain() é a entrada para a aplicação Windows, usará ela em vez da main(). A imagem estática é criada na WndProc() pela função CreateWindowW().

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho Vou postar o código do exemplo que mostrei em #8. De resto não posso te ajudar, não sei o que está tentando fazer e você não me diz (em detalhes). 🤪

Das funções que eu escrevi nesse código:

  • GetBitmapPixel() salva em um arquivo texto o tamanho e a cor dos pixels do bitmap carregado de um diretório por Loadhbit().
  • CreateBitmapPixel() lê os dados do bitmap do arquivo texto, cria o bitmap e o retorna para que seja usado pela função SendMessage() chamada após CreateWindowW(), isso tudo a fim de criar na janela a imagem estática.
  • DrawImagePixel() lê os dados do bitmap do arquivo texto e o desenha na janela pixel a pixel. Se for testar, descomente da linha 118 à 126, comente da 107 à 117 e mude a linha 240 para
    fprintf(fp, "%u", COLORREFxRGB(ptPixels[i]));
    já que SetPixel() precisa da cor em COLORREF.

Alias, img.bmp deve estar na mesma pasta que a main.c. Ou então mude o diretório na função Loadhbit().

#define ID_IMAGE 1

#define COLORREFxRGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                 | ((Color << 16) & 0xff0000)

#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>

typedef struct
{
    HBITMAP bitm;
    long bmWidth;
    long bmHeight;
} BITDATA;

int WindowX(void);
int WindowY(void);
HBITMAP Loadhbit(const char * load);
BITDATA GetBitmapPixel(HBITMAP hBmp, const char* dir);
int DrawImagePixel(long xStr, long yStr, const char* dir, HWND hwnd);
HBITMAP CreateBitmapPixel(const char* dir);

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

HWND hWnd = GetConsoleWindow();

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG msg;                 /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = CreateSolidBrush(RGB(255,255,255));

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Pixel image"),   /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    ShowWindow(hWnd, SW_MINIMIZE);
    //won't hide the window without SW_MINIMIZE
    ShowWindow(hWnd, SW_HIDE);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&msg, NULL, 0, 0))
    {
        /* Translate virtual-key msg into character msg */
        TranslateMessage(&msg);
        /* Send message to WindowProcedure */
        DispatchMessage(&msg);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return msg.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND bk;
    switch (message)             /* handle the msg */
    {
        //
        case WM_CREATE:
        {
            GetBitmapPixel(Loadhbit("img.bmp"), "pixel.txt");
            bk = CreateWindowW(L"Static", L"", WS_CHILD | WS_VISIBLE | SS_BITMAP,
                               0, 0, WindowX(), WindowY(), hwnd, (HMENU) ID_IMAGE,
                               NULL, NULL);
            SendMessage(bk, STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) CreateBitmapPixel("pixel.txt"));
        }
        break;
        //
        /*
        case WM_PAINT :
        {
            Sleep(400);
            GetBitmapPixel(Loadhbit("img.bmp"), "pixel.txt");
            DrawImagePixel(0, 0, "pixel.txt", hwnd);
        }
        break;
        */
        case WM_CLOSE:
        {
            MessageBeep(MB_OK);
            if (MessageBox(hwnd, "Deseja realmente sair?", "Pixel image", MB_OKCANCEL) == IDOK)
            {
                DestroyWindow(hwnd);
            } else {
                return 0;
            }
        }
        break;
        case WM_DESTROY:
        {
            // Fechar o programa
            PostQuitMessage(0);
            // Fechar a console
            PostMessage(hWnd, WM_CLOSE, 0, 0);
        }
        break;
        default:                 /* for msg that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

int WindowX(void)
{
    // Tamanho do desktop eixo X
	RECT desktop_rect_;
	HWND desktop_ = GetDesktopWindow();
	GetWindowRect(desktop_, &desktop_rect_);
	return desktop_rect_.right;
}

int WindowY(void)
{
    // Tamanho do desktop eixo Y
	RECT desktop_rect_;
	HWND desktop_ = GetDesktopWindow();
	GetWindowRect(desktop_, &desktop_rect_);
	return desktop_rect_.bottom;
}

HBITMAP Loadhbit(const char * load)
{
    HBITMAP hBitmap = (HBITMAP) LoadImage(NULL, (LPCSTR)load, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    if(hBitmap == NULL){
        // Exibe uma caixa de dialogo se algo ocorrer errado
        MessageBox(NULL, "Erro ao carregar imagem", "Error", MB_OK|MB_ICONERROR);
    }

    return hBitmap;
}

BITDATA GetBitmapPixel(HBITMAP hBmp, const char* dir)
{
    FILE *fp = fopen(dir, "w");
    BITDATA RetBmp;
    HDC hBmpDC = NULL;
    if (hBmp)
    {
        // DC para bitmap de origem
        HDC BufferDC = CreateCompatibleDC(NULL);
        if (BufferDC)
        {
            HBITMAP hTmpBitmap = (HBITMAP) NULL;
            if (hBmpDC)
                if (hBmp == (HBITMAP)GetCurrentObject(hBmpDC, OBJ_BITMAP))
            {
                hTmpBitmap = CreateBitmap(1, 1, 1, 1, NULL);
                SelectObject(hBmpDC, hTmpBitmap);
            }

            HGDIOBJ PreviousBufferObject = SelectObject(BufferDC,hBmp);
            // BufferDC contem o bitmap

            HDC DirectDC = CreateCompatibleDC(NULL);
            if (DirectDC)
            {
                // Obtendo o tamanho do bitmap
                BITMAP bm;
                GetObject(hBmp, sizeof(bm), &bm);

                // criando um BITMAPINFO para a CreateDIBSection()
                BITMAPINFO RGB32BitsBITMAPINFO;
                ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
                RGB32BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                RGB32BitsBITMAPINFO.bmiHeader.biWidth = bm.bmWidth;
                RGB32BitsBITMAPINFO.bmiHeader.biHeight = bm.bmHeight;
                RGB32BitsBITMAPINFO.bmiHeader.biPlanes = 1;
                RGB32BitsBITMAPINFO.bmiHeader.biBitCount = 32;

                // Ponteiro para acesso aos pixels do bitmap
                UINT* ptPixels;

                HBITMAP DirectBitmap = CreateDIBSection(DirectDC,
                                       (BITMAPINFO *)&RGB32BitsBITMAPINFO,
                                       DIB_RGB_COLORS,
                                       (void **)&ptPixels,
                                       NULL, 0);
                if (DirectBitmap)
                {
                    HGDIOBJ PreviousObject = SelectObject(DirectDC, DirectBitmap);
                    BitBlt(DirectDC, 0, 0, bm.bmWidth,bm.bmHeight, BufferDC, 0, 0, SRCCOPY);
                    // DirectDC contem o bitmap

                    // Gravando tamanho do bitmap no arquivo
                    fprintf(fp, "%ld\n%ld\n", bm.bmWidth, bm.bmHeight);

                    // Gravando a cor dos pixels no arquivo
                    for (int i= ((bm.bmWidth*bm.bmHeight)-1); i>=0; i--)
                    {
                        fprintf(fp, "%u", ptPixels[i]);
                        if(i > 0) fputc('\n', fp);
                    }
                    // Limpeza
                    SelectObject(DirectDC,PreviousObject);

                    // Preparando retorno
                    RetBmp.bitm = DirectBitmap;
                    RetBmp.bmWidth = bm.bmWidth;
                    RetBmp.bmHeight = bm.bmHeight;
                }
                // Limpeza
                DeleteDC(DirectDC);
            }
            if (hTmpBitmap)
            {
                SelectObject(hBmpDC, hBmp);
                DeleteObject(hTmpBitmap);
            }
            SelectObject(BufferDC,PreviousBufferObject);
            DeleteDC(BufferDC);
        }
    }

    fclose(fp);
    return RetBmp;
}

int DrawImagePixel(long xStr, long yStr, const char* dir, HWND hwnd)
{
    PAINTSTRUCT ps;
    RECT r;

    GetClientRect(hwnd, &r);
    HDC hdc = BeginPaint(hwnd, &ps);

    FILE *fp = fopen(dir, "r");
    if (fp == NULL)
    {
        return 1;
    }

    long bmWidth = 0;
    long bmHeight = 0;
    UINT pixel = 0;

    // Lendo tamanho do bitmap
    fscanf(fp, "%ld %ld", &bmWidth, &bmHeight);

    for(int i = yStr; i < (bmHeight + yStr); i++)
    {
        for(int j = xStr; j < (bmWidth + xStr); j++)
        {
            // Lendo do arquivo e pintando pixel a pixel
            fscanf(fp, " %u", &pixel);
            SetPixel(hdc, j, i, pixel);
        }
    }

    EndPaint(hwnd, &ps);

    return 0;
}

HBITMAP CreateBitmapPixel(const char* dir)
{
    long bmWidth = 0;
    long bmHeight = 0;
    long long cont = 0;

    FILE *fp = fopen(dir, "r");
    if (fp == NULL)
    {
        return NULL;
    }

    // Lendo tamanho do bitmap
    fscanf(fp, "%ld %ld", &bmWidth, &bmHeight);

    // Vetor de pixels
    unsigned int* pixels = (unsigned int*)malloc(bmWidth*bmHeight*sizeof(unsigned int));

    for(int i = 0; i < bmHeight; i++)
    {
        for(int j = 0; j < bmWidth; j++)
        {
            // Lendo do arquivo e gravando no vetor
            fscanf(fp, " %u", &pixels[cont++]);
        }
    }

    // Criando o bitmap
    return CreateBitmap(bmWidth, bmHeight, 1, 32, pixels);
}
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

como funciona a minha classe image e desenhar a imagem:
1 - posso criar 1 image usando um tamanho ou 1 ficheiro;

2 - para ler um ficheiro, eu uso as funções GDIPlus;
3 - para criar 1 imagem, posso usar funções GDI;
3 - poder desenhar a imagem em qualquer HDC ou isso usando os 4 cantos;
4 - a rotação não posso usar a mesma função, porque tenho de usar 1 posição 3D(se for 2D, o Z é zero).

 

correcções:

1 - ao usar a 'malloc()', tenho de usar a 'free()'?
2 - ao reutilizar a 'malloc()' tenho de usar o 'new'?

tenho de rever a minha função\classe toda para poder fazer a diferença... depois voltarei.. muito obrigado por tudo

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@Cambalinho Talvez @arfneto ou algum outro colega saiba te direcionar melhor.

Só quis te dar uma ideia de como resolver aquele problema inicial da SetPixel()

Em 15/02/2022 às 17:00, Cambalinho disse:

este codigo faz o que preciso: desenha 1 imagem pixel a pixel... mas preciso de velocidade... então queria ver como posso ganhar mais velocidade...

 

De C++ não entendo tanto. 🤪

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

olhe uma coisa: eu preciso de evitar os memory leaks.. isso é normal.

para evitar isso: tenho de deletar o objecto HBITMAP antes de o criar... como o testo para o deletar?

será:
 

if(HBitmap) DeleteObject(HBitmap);

???
o mesmo vai para os outros objectos também

prontos actualizei 1 pouco a minha classe image:

#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <vector>
#include <gdiplus.h>
#include <stdlib.h>
#include <algorithm>
#include<thread>
/*void foo(param)
{
    // Do something
}

// The parameters to the function are put after the comma
std::thread thread_obj(foo, params);*/

using namespace Gdiplus;
using namespace std;

const double PI = 3.14159265358979;

struct point
{
    float x,y,z;
} ;

struct angle
{
    float x,y,z;
} ;


//Convert the std::string to std::wstring:
std::wstring towstring(const std::string& v)
{
    std::wstring out(v.size()+1,L'\0');

    int size = MultiByteToWideChar(CP_UTF8, 0, v.c_str(), -1, &out[0], out.size());

    out.resize(size-1);
    return out;
}

class line
{
    public:
        point OriginLine;
        point DestinationLine;

    line(point origin,point destination)
    {
        OriginLine=origin;
        DestinationLine=destination;
    }

    float GetLineLength(point p1,point p2)
    {
        return sqrt( (p1.x-p2.x)* (p1.x-p2.x) + (p1.y-p2.y)* (p1.y-p2.y) + (p1.z-p2.z)* (p1.z-p2.z));
    }

    //Get Points Line:
    point lineto(point fp,point p,float length)
    {
        point res;
        float L=GetLineLength(fp,p);
        res.x=fp.x+length*(p.x-fp.x)/L;
        res.y=fp.y+length*(p.y-fp.y)/L;
        res.z=fp.z+length*(p.z-fp.z)/L;
        return res;
    }

    point perspective(const point &p,const point &eyepoint={250,150,300})
    {
        float   w=1+(p.z/eyepoint.z);
        return {(p.x-eyepoint.x)/w+eyepoint.x,
        (p.y-eyepoint.y)/w+eyepoint.y,
        (p.z-eyepoint.z)/w+eyepoint.z};
    }

    vector<point> GetPointsLine()
    {
        point t=OriginLine;
        vector<point> coordenates;
        float dst=GetLineLength(OriginLine,DestinationLine);
        for (int i=0;i<=dst;i++)
        {
            t=lineto(t,DestinationLine,1);
            t=perspective(t);
            coordenates.push_back(t);
        }
        return coordenates;
    }
};

POINT Convert3DTo2D(point Dot, int FocalDistance=100)
{
    POINT ptDot;
    ptDot.x=Dot.x/Dot.z * FocalDistance;
    ptDot.y=Dot.y/Dot.z * FocalDistance;
    return ptDot;
}

class image
{
    public:

    ULONG_PTR m_gdiplusToken=NULL;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Graphics *graphic=nullptr;
    Gdiplus::Bitmap *img;
    unsigned int* pixels;
    HDC ImageHDC=NULL;
    int Width=0;
    int Height=0;
    HBITMAP hBitmap;

    void GetHDC(HDC &imgHDC)
    {
        imgHDC=graphic->GetHDC();
    }

    void ReleaseHDC(HDC &imgHDC)
    {
        graphic->ReleaseHDC(imgHDC);
    }

    image()
    {
        //nothing:
    }

    /*image(int SizeWidth, int SizeHeight)
    {
        New(SizeWidth, SizeHeight);

    }*/

    image(string strFile)
    {
        FromFile(strFile);
    }

    void Clear(Color BackColor=Color::White)
    {
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);
    }

    void New(int Width, int Height,Color BackColor=Color::White)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img=new Gdiplus::Bitmap(Width, Height);
        graphic=new Gdiplus::Graphics(img);
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);

        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        Color clr(0x00,0x00,0x00);
        HBITMAP *hBitmap;
        //Gdiplus::Bitmap *img;
        img->GetHBITMAP(clr,hBitmap);
        DIBSECTION dibs;
        ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
        BITMAPINFO bitinfo;
        ::GetObject(hBitmap, sizeof(BITMAPINFO), &bitinfo);
        ::GetDIBits(graphic->GetHDC(), *hBitmap,0,0,&pixels,&bitinfo,dibs.dsBmih.biClrUsed);
        delete Fill;
    }

    void Dispose()
    {
        //clear all objects for avoid memory leaks:
        if(m_gdiplusToken)
        {
            Gdiplus::GdiplusShutdown(m_gdiplusToken);
        }
        //by some reason, i can't delete the 'new' values: 'img' and 'graphic'
        //the program terminates with an exit error
    }

    ~image()
    {
        Dispose();
    }

    void FromFile(string strFile)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();
        graphic= Graphics::FromImage(this->img);
        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        hBitmap= CreateBitmap(Width, Height, 1, 32, pixels);
        ImageHDC = CreateCompatibleDC(GetDC(NULL));
        SelectObject(ImageHDC, hBitmap);
        Graphics *g;
        g=Graphics::FromHDC(ImageHDC);
        g->DrawImage(img,0,0);

    }

    void DrawImage(HDC DestinationHDC, int PosX=0, int PosY=0, COLORREF TransparentColor=RGB(0,0,0))
    {
        TransparentBlt(DestinationHDC,0,0,Width,Height,ImageHDC,0,0,Width,Height,TransparentColor);

    }


    //Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight, angle angles={0,0,0})
    {
        //Getting the Points of a line:
        vector<point> LeftLine;
        //TopLeft = RotationPoints(TopLeft,angles);
        //TopRight = RotationPoints(TopRight,angles);
        //BottomLeft = RotationPoints(BottomLeft,angles);
        //BottomRight = RotationPoints(BottomRight,angles);
        line LineLeft(TopLeft,BottomLeft);
        LeftLine = LineLeft.GetPointsLine();
        vector<point> RgihtLine;
        line LineRight(TopRight,BottomRight);
        RgihtLine=LineRight.GetPointsLine();


        for(int PosX=0; PosX<LeftLine.size(); PosX++)
        {
            vector<point> PixelLine;
            line LinePixel(LeftLine[PosX], RgihtLine[PosX]);
            PixelLine=LinePixel.GetPointsLine();

            for (int PosY=0; PosY<PixelLine.size(); PosY++)
            {
                point Point=PixelLine[PosY];

                //Get the pixel:
                COLORREF clr;
                BYTE Red = pixels[(PosX*Width+PosY) + 2]; // obtemos Red;
                BYTE Green = pixels[(PosX*Width+PosY) + 1]; // obtemos Green;
                BYTE Blue = pixels[(PosX*Width+PosY) + 0]; // obtemos Blue;
                BYTE Alpha = pixels[(PosX*Width+PosY) + 3]; // obtemos Alpha;
                clr=RGB(Red, Green,Blue);
                ::SetPixel(hdcDestination,PosY,PosX,clr);
            }
        }
    }
};

como a uso:

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());
    point TopLeft={100, 200,0};
    point TopRight={200,200,0};
    point BottomLeft={100,300,0};
    point BottomRight={200,300,0};

    point RotationPoint={250,150,0};//center of rectangle
    angle angles;
    image img("c:\\1595973613452.bmp");


    RECT a;

    a.left=0;
    a.right=800;
    a.top=0;
    a.bottom=800;
	do
    {
        //angles.x+=0.1;
        //TopLeft:
        point TopLeftRotated=TopLeft;//RotationPoints(TopLeft,{angles.x,angles.y,angles.z},RotationPoint);
        //TopRight:
        point TopRightRotated=TopRight;//RotationPoints(TopRight,{angles.x,angles.y,angles.z},RotationPoint);
        //BottomLeft:
        point BottomLeftRotated=BottomLeft;//RotationPoints(BottomLeft,{angles.x,angles.y,angles.z},RotationPoint);
        //BottomRight:
        point BottomRightRotated=BottomRight;//RotationPoints(BottomRight,{angles.x,angles.y,angles.z},RotationPoint);
        img.DrawImage(WindowHDC);



        Sleep(100);

        FillRect(WindowHDC,&a, CreateSolidBrush(RGB(0,0,0)));
    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));//press escape for exit
    cout<<"Press return to end . . ."<<endl;
    cin.get();
}

a imagem é mostrada... agora estou a ver se o pixels for mesmo criado correctamente:

void FromFile(string strFile)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();
        graphic= Graphics::FromImage(this->img);
        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        hBitmap= CreateBitmap(Width, Height, 1, 32, pixels);
        ImageHDC = CreateCompatibleDC(GetDC(NULL));
        SelectObject(ImageHDC, hBitmap);
        Graphics *g;
        g=Graphics::FromHDC(ImageHDC);
        g->DrawImage(img,0,0);

    }

aqui mostra normal:

void DrawImage(HDC DestinationHDC, int PosX=0, int PosY=0, COLORREF TransparentColor=RGB(0,0,0))
    {
        TransparentBlt(DestinationHDC,0,0,Width,Height,ImageHDC,0,0,Width,Height,TransparentColor);

    }

mas aqui não obtenho as cores 😞
mas vou simplificar esta função:

//Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight, angle angles={0,0,0})
    {
        //Getting the Points of a line:
        vector<point> LeftLine;
        //TopLeft = RotationPoints(TopLeft,angles);
        //TopRight = RotationPoints(TopRight,angles);
        //BottomLeft = RotationPoints(BottomLeft,angles);
        //BottomRight = RotationPoints(BottomRight,angles);
        line LineLeft(TopLeft,BottomLeft);
        LeftLine = LineLeft.GetPointsLine();
        vector<point> RgihtLine;
        line LineRight(TopRight,BottomRight);
        RgihtLine=LineRight.GetPointsLine();


        for(int PosX=0; PosX<LeftLine.size(); PosX++)
        {
            vector<point> PixelLine;
            line LinePixel(LeftLine[PosX], RgihtLine[PosX]);
            PixelLine=LinePixel.GetPointsLine();

            for (int PosY=0; PosY<PixelLine.size(); PosY++)
            {
                point Point=PixelLine[PosY];

                //Get the pixel:
                COLORREF clr;
                BYTE Red = pixels[(PosX*Width+PosY) + 2]; // obtemos Red;
                BYTE Green = pixels[(PosX*Width+PosY) + 1]; // obtemos Green;
                BYTE Blue = pixels[(PosX*Width+PosY) + 0]; // obtemos Blue;
                BYTE Alpha = pixels[(PosX*Width+PosY) + 3]; // obtemos Alpha;
                clr=RGB(Red, Green,Blue);
                ::SetPixel(hdcDestination,PosY,PosX,clr);
            }
        }
    }

 

simplifiquei a função ao máximo para testar:

//Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination)
    {
        //Obter o HBITMAP de um HDC:
        HBITMAP hBmp = reinterpret_cast<HBITMAP>(GetCurrentObject(hdcDestination, OBJ_BITMAP));
        
        //Obter o BITMAPINFOHEADER do HBITMAP e os pixels:
        memset(&bmi, 0, sizeof(bmi));
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        unsigned int*pixels2 = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        GetDIBits(hdcDestination, hBmp, 0, 1, pixels2, (BITMAPINFO *)&bmi,
                DIB_RGB_COLORS);
        //obter o tamanho do array:
        int pixelscount=Width*Height*sizeof(unsigned int);
        
        for(int i=0; i<pixelscount; i++)
        {
            //copiar a imagem origem para o HDC destino:
            pixels2[i]=pixels[i];

        }
    }

após execução, eu obtenho 1 erro:

fiz mais testes e o  'pixelscount' está mal calculado 😞
eu meti 300 para testar e não tenho pixels 😞

o que estou a fazer errado?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho     Qual compilador / IDE você está usando ?  ,   pois testei seu código aqui  no codeblocks e    não       nem compilou  ,  erros com mensagem de bibliotecas que não existem ,  e você postou dois códigos separados ,  como juntar esses dois códigos ?  ,  e fui tentando consertar o código e acabou ficando assim  :

#define _WIN32_WINNT 0x0600
#include <stdio.h>  // coloque isso (-lgdi32 ) no linker do compilador codeblocks
#include <conio.h>
#include <windows.h>
#define H GetStdHandle(STD_OUTPUT_HANDLE)
#define pi 3.141592
#define SEN sin(n*pi/180)
#define COS cos(n*pi/180)
#define cls ;system("cls || clear");InvalidateRect(csl,NULL,TRUE);
void girar_M_Thor(int _fx);
void grafico(            );
int _x,_y,j,i,_fx         ;
HWND     csl              ;
HDC      hdc              ;
COLORREF cor,cor_fundo    ;
POINT    pt[4            ];
HBRUSH   NewBrush         ;
RECT     rect1            ;
void init_graph(){ /// colocar no inicio de cada programa , para pegar o controle do console
    cor       = RGB(  255 , 255 ,   0      );
    cor_fundo = RGB(    5 , 255 , 250      );
    csl       = GetConsoleWindow(          );
    hdc       = GetDC(  csl                );
    NewBrush  = CreateSolidBrush(cor_fundo );
    SelectObject(hdc,NewBrush);
    ///    setlocale(LC_ALL,"portuguese");       //  este aqui modifica a tabela de caracteres
}
typedef enum{ black     ,blue    ,green    ,cyan      ,red      ,magenta ,brown       ,
              lightgray ,darkgray,lightblue,lightgreen,lightcyan,lightred,lightmagenta,
              yellow    ,white   }                                              colors;
void textcolor_2( int _l, int _f ){ SetConsoleTextAttribute ( H , _l + ( _f << 4 ) ) ;}
void    gotoxy_2( int Mx, int My ){ SetConsoleCursorPosition( H , ( COORD ){ Mx, My});}
int     som     ( int Mf){          Beep ( Mf , 150 )                                ;}
void    pix     ( float sn,float cs,int h2, COLORREF cor                             ){
    int w2,i2;
    for(w2=0;w2<h2;w2++)
        for(i2=0;i2<h2;i2++)
            SetPixel(hdc,sn+w2,cs+i2,cor);      /// desenha um ponto com grossura h2
}
void oval(int Mk ,int Ml,int Mth,int Mtv,       /// desenhar um circulo que pode ser Ovalado
          int Mh,COLORREF cor          ){       /// coluna linha inicial ,tam horiz tam vertic
    float sn,cs                         ;       /// grossura do traço
    int n                               ;
    if(Mh<1)Mh=1;else if(Mh>10)Mh=10    ;
    for( n = 0; n<360; n++             ){       /// SEN e COS está nos define
        sn = SEN * Mth + Mk             ;       /// coluna da tela (640) pixels
        cs = COS * Mtv + Ml             ;       /// linha da tela  (400) pixels
        pix(sn,cs,Mh,cor);
    }
}
void drawline( float x , float y , float x_f,
              float y_f,int Gr,COLORREF cor){
    float dx = x_f - x, dy = y_f-y, steps,Mk;
    if(abs(dx)  > abs( dy))steps = abs( dx );
    else steps  = abs(dy)    ;
    float inc_x = dx / steps ;
    float inc_y = dy / steps ;
    for(Mk=0; Mk<steps; Mk++){
        x += inc_x           ;
        y += inc_y           ;
        pix( x , y , Gr ,cor);
    }
}
void rect( int   k,int l,int tmh,int tmv, int hg,   /// desenhar um retângulo que pode ser um quad
           int Pre,COLORREF cor                ){   /// koluna Linha tam_H tam_V Grossura do traço
    drawline(k    ,l    ,  k+tmh,l      ,hg,cor);
    drawline(k    ,l+tmv,  k+tmh,l+tmv  ,hg,cor);
    drawline(k    ,l    ,  k    ,l+tmv  ,hg,cor);
    drawline(k+tmh,l    ,  k+tmh,l+tmv  ,hg,cor);
    SetPixel(hdc,k,l    ,  cor                 );
    float j,i                                   ;
    if(Pre != 0                                ){
        for(j=k+hg;j<k+tmh;j++                  )
            for(i=l+hg;i<l+tmv;i++              )
                SetPixel(hdc,j,i,cor_fundo     );
    }
}
void gotoYX(int x, int y    ){
    SetConsoleCursorPosition (
    H , ( COORD ) { x , y  });
}
//   ====================================================
//   |   |==========================================|   |
/*   |   |*/    int main(                  ){    // |   |
/*   |   |*/        init_graph(            );    // |   |
/*   |   |*/        grafico(               );    // |   |
/*   |   |*/        while( ! kbhit( )      ){    // |   |
/*   |   |*/            girar_M_Thor( _fx  );    // |   |
/*   |   |*/            _fx += 6            ;    // |   |
/*   |   |*/            if( _fx > 360       )    // |   |
/*   |   |*/                _fx = 000       ;    // |   |
/*   |   |*/        }                            // |   |
/*   |   |*/        textcolor_2(7,0        );    // |   |
/*   |   |*/        return 0                ;    // |   |
/*   |   |*/    }                                // |   |
//   |   ============================================   |
//   ====================================================
void grafico(                   ){
    int fx,x,y,k,w               ;
    float a                      ;
    for(fx=0; fx<361; fx+=5     ){
        a = fx*3.141591/180      ;
        x = cos( a )*101+700     ;
        y = sin( a )*101+240     ;
        k = cos( a )*189+700     ;
        w = sin( a )*189+240     ;
        drawline( x,y,k,w,1,cor );
        cor = RGB(255,255,0     );
        pix(x ,y ,6,cor         );
        pix(k ,w ,6,cor         );
        Sleep(  1               );
    }
}
void girar_M_Thor(    int _fx                ){
    int x,y,x1,y1,w,C=0,vx[100][2]            ;
    x1 = cos((_fx+30)*3.141591/180)*60+700    ;
    y1 = sin((_fx+30)*3.141591/180)*60+240    ;
    x = x1;   y = y1                          ;
    cor = RGB(255,255,0                      );
    drawline( 700,240,x1,y1,2,cor            );
    cor = RGB(255,2,0                        );
    for(w=_fx; w<_fx+60; w++                 ){
        vx[C][0] = cos(w*3.141591/180)*60+700 ;
        vx[C][1] = sin(w*3.141591/180)*60+240 ;
        pix(vx[C][0],vx[C][1],4,cor          );
        C++                                   ;
    }
    Sleep(      20                           );
    cor = RGB (  0       ,  0 ,0             );
    drawline  (700       ,240 ,x,y  ,4, cor  );
    pix       (vx[0][0]-2,vx[0][1]-2,8, cor  );
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

 

boa noite.

aqui está:
image.h:

#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <vector>
#include <gdiplus.h>
#include <stdlib.h>
#include <algorithm>
#include<thread>
/*void foo(param)
{
    // Do something
}

// The parameters to the function are put after the comma
std::thread thread_obj(foo, params);*/

using namespace Gdiplus;
using namespace std;

const double PI = 3.14159265358979;

struct {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD bmiColors[256];
} bmi;

struct point
{
    float x,y,z;
} ;

struct angle
{
    float x,y,z;
} ;


//Convert the std::string to std::wstring:
std::wstring towstring(const std::string& v)
{
    std::wstring out(v.size()+1,L'\0');

    int size = MultiByteToWideChar(CP_UTF8, 0, v.c_str(), -1, &out[0], out.size());

    out.resize(size-1);
    return out;
}

class line
{
    public:
        point OriginLine;
        point DestinationLine;

    line(point origin,point destination)
    {
        OriginLine=origin;
        DestinationLine=destination;
    }

    float GetLineLength(point p1,point p2)
    {
        return sqrt( (p1.x-p2.x)* (p1.x-p2.x) + (p1.y-p2.y)* (p1.y-p2.y) + (p1.z-p2.z)* (p1.z-p2.z));
    }

    //Get Points Line:
    point lineto(point fp,point p,float length)
    {
        point res;
        float L=GetLineLength(fp,p);
        res.x=fp.x+length*(p.x-fp.x)/L;
        res.y=fp.y+length*(p.y-fp.y)/L;
        res.z=fp.z+length*(p.z-fp.z)/L;
        return res;
    }

    point perspective(const point &p,const point &eyepoint={250,150,300})
    {
        float   w=1+(p.z/eyepoint.z);
        return {(p.x-eyepoint.x)/w+eyepoint.x,
        (p.y-eyepoint.y)/w+eyepoint.y,
        (p.z-eyepoint.z)/w+eyepoint.z};
    }

    vector<point> GetPointsLine()
    {
        point t=OriginLine;
        vector<point> coordenates;
        float dst=GetLineLength(OriginLine,DestinationLine);
        for (int i=0;i<=dst;i++)
        {
            t=lineto(t,DestinationLine,1);
            t=perspective(t);
            coordenates.push_back(t);
        }
        return coordenates;
    }
};

POINT Convert3DTo2D(point Dot, int FocalDistance=100)
{
    POINT ptDot;
    ptDot.x=Dot.x/Dot.z * FocalDistance;
    ptDot.y=Dot.y/Dot.z * FocalDistance;
    return ptDot;
}

class image
{
    public:

    ULONG_PTR m_gdiplusToken=NULL;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Graphics *graphic=nullptr;
    Gdiplus::Bitmap *img;
    unsigned int* pixels;
    HDC ImageHDC=NULL;
    int Width=0;
    int Height=0;
    HBITMAP hBitmap;

    void GetHDC(HDC &imgHDC)
    {
        imgHDC=graphic->GetHDC();
    }

    void ReleaseHDC(HDC &imgHDC)
    {
        graphic->ReleaseHDC(imgHDC);
    }

    image()
    {
        //nothing:
    }

    /*image(int SizeWidth, int SizeHeight)
    {
        New(SizeWidth, SizeHeight);

    }*/

    image(string strFile)
    {
        FromFile(strFile);
    }

    void Clear(Color BackColor=Color::White)
    {
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);
    }

    void New(int Width, int Height,Color BackColor=Color::White)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img=new Gdiplus::Bitmap(Width, Height);
        graphic=new Gdiplus::Graphics(img);
        SolidBrush *Fill=new SolidBrush(BackColor);
        graphic->FillRectangle(Fill,0,0,Width,Height);

        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        Color clr(0x00,0x00,0x00);
        HBITMAP *hBitmap;
        //Gdiplus::Bitmap *img;
        img->GetHBITMAP(clr,hBitmap);
        DIBSECTION dibs;
        ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
        BITMAPINFO bitinfo;
        ::GetObject(hBitmap, sizeof(BITMAPINFO), &bitinfo);
        ::GetDIBits(graphic->GetHDC(), *hBitmap,0,0,&pixels,&bitinfo,dibs.dsBmih.biClrUsed);
        delete Fill;
    }

    void Dispose()
    {
        //clear all objects for avoid memory leaks:
        if(m_gdiplusToken)
        {
            Gdiplus::GdiplusShutdown(m_gdiplusToken);
        }
        //by some reason, i can't delete the 'new' values: 'img' and 'graphic'
        //the program terminates with an exit error
    }

    ~image()
    {
        Dispose();
    }

    void FromFile(string strFile)
    {
        Dispose();
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();
        graphic= Graphics::FromImage(this->img);
        //getting the hbitmap, hbitmapinfo and dibs\pixels:
        pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));
        hBitmap= CreateBitmap(Width, Height, 1, 32, pixels);
        ImageHDC = CreateCompatibleDC(GetDC(NULL));
        SelectObject(ImageHDC, hBitmap);
        Graphics *g;
        g=Graphics::FromHDC(ImageHDC);
        g->DrawImage(img,0,0);

    }

    void DrawImage(HDC DestinationHDC, int PosX=0, int PosY=0, COLORREF TransparentColor=RGB(0,0,0))
    {
        TransparentBlt(DestinationHDC,0,0,Width,Height,ImageHDC,0,0,Width,Height,TransparentColor);

    }


    //Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight, angle angles={0,0,0})
    {
        //Getting the Points of a line:
        vector<point> LeftLine;
        //TopLeft = RotationPoints(TopLeft,angles);
        //TopRight = RotationPoints(TopRight,angles);
        //BottomLeft = RotationPoints(BottomLeft,angles);
        //BottomRight = RotationPoints(BottomRight,angles);
        line LineLeft(TopLeft,BottomLeft);
        LeftLine = LineLeft.GetPointsLine();
        vector<point> RgihtLine;
        line LineRight(TopRight,BottomRight);
        RgihtLine=LineRight.GetPointsLine();


        for(int PosX=0; PosX<LeftLine.size(); PosX++)
        {
            vector<point> PixelLine;
            line LinePixel(LeftLine[PosX], RgihtLine[PosX]);
            PixelLine=LinePixel.GetPointsLine();

            for (int PosY=0; PosY<PixelLine.size(); PosY++)
            {
                point Point=PixelLine[PosY];

                //Get the pixel:
                COLORREF clr;
                BYTE Red = pixels[(PosX*Width+PosY) + 2]; // obtemos Red;
                BYTE Green = pixels[(PosX*Width+PosY) + 1]; // obtemos Green;
                BYTE Blue = pixels[(PosX*Width+PosY) + 0]; // obtemos Blue;
                BYTE Alpha = pixels[(PosX*Width+PosY) + 3]; // obtemos Alpha;
                clr=RGB(Blue, Green,Red);
                ::SetPixel(hdcDestination,PosY,PosX,clr);
            }
        }
    }
};

main.cpp:

#include <iostream>
#include <string>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <vector>
#include <gdiplus.h>
#include <stdlib.h>
#include <algorithm>
#include <thread>
#include <future>
#include "image.h"

using namespace Gdiplus;
using namespace std;

/*const double PI = 3.14159265358979;

struct point
{
    float x,y,z;
} ;

struct angle
{
    float x,y,z;
} ;*/

point Convert3DTO2D(point Position, float FocalDistance=0.05)
{
    point Point2D;
    Point2D.x=Position.x * FocalDistance/Position.z;
    Point2D.y=Position.y*FocalDistance/Position.z;
    return Point2D;
}

angle ConvertDegreesToRadians(angle Rotation)
{

    double deg2Rad;
    deg2Rad = PI / 180;
    angle ConvertDegrees;
    ConvertDegrees.x = Rotation.x * deg2Rad;
    ConvertDegrees.y = Rotation.y * deg2Rad;
    ConvertDegrees.z = Rotation.z * deg2Rad;
    return ConvertDegrees;
}

point RotationPoints2(point Coordenate, const angle AngleCoordenate, const point pivot={0,0,0})
{
    angle radians= ConvertDegreesToRadians(AngleCoordenate);
    point RotatedPoint;
    RotatedPoint=Coordenate;
    Coordenate.x-=pivot.x;
    Coordenate.y-=pivot.y;
    Coordenate.z-=pivot.z;
    //First we rotate the Z:
    RotatedPoint.x=Coordenate.x * cos(AngleCoordenate.z)-Coordenate.y*sin(AngleCoordenate.z);
    RotatedPoint.y=Coordenate.x * sin(AngleCoordenate.z)+Coordenate.y*cos(AngleCoordenate.z);
    //RotatedPoint.z=Coordenate.z;

    //Second we rotate the Y:
    RotatedPoint.x=RotatedPoint.x * cos(AngleCoordenate.y)+RotatedPoint.z*sin(AngleCoordenate.y);
    //RotatedPoint.y=RotatedPoint.y;  // pointless self assignemnt
    RotatedPoint.z=-RotatedPoint.x * sin(AngleCoordenate.y)+RotatedPoint.z*cos(AngleCoordenate.y);

    //Third we rotate the X:
    //RotatedPoint.x=RotatedPoint.x;   // pointless self assignemnt
    RotatedPoint.y=RotatedPoint.y * cos(AngleCoordenate.x)-RotatedPoint.z*sin(AngleCoordenate.x);
    RotatedPoint.z=RotatedPoint.y * sin(AngleCoordenate.x)+RotatedPoint.z*cos(AngleCoordenate.x);

    RotatedPoint.x+=pivot.x;
    RotatedPoint.y+=pivot.y;
    RotatedPoint.z+=pivot.z;
    return RotatedPoint;
}

point RotationPoints(point pt, angle Angle, point pivot={0,0,0},point scale={1,1,1})
{
    angle radians= ConvertDegreesToRadians(Angle);
    Angle.x =radians.x;
    Angle.y =radians.y;
    Angle.z =radians.z;
    point p={pt.x-pivot.x,pt.y-pivot.y,pt.z-pivot.z};
    point rot,temp;
    temp={(p.y)*cos(Angle.x)+(-p.z)*sin(Angle.x),(p.z)*cos(Angle.x)+(p.y)*sin(Angle.x)};
    rot.y=temp.x;rot.z=temp.y;
    p.y = rot.y;p.z = rot.z;
    temp={(p.z)*cos(Angle.y)+(-p.x)*sin(Angle.y),(p.x)*cos(Angle.y)+(p.z)*sin(Angle.y)};
    rot.z=temp.x;rot.x=temp.y;
    p.x=rot.x;
    temp={(p.x)*cos(Angle.z)+(-p.y)*sin(Angle.z),(p.y)*cos(Angle.z)+(p.x)*sin(Angle.z)};
    rot.x=temp.x;rot.y=temp.y;
    return {(scale.x*rot.x+pivot.x),(scale.y*rot.y+pivot.y),(scale.z*rot.z+pivot.z)};
}

float GetLineLength(point p1,point p2)
{
	return sqrt( (p1.x-p2.x)* (p1.x-p2.x) + (p1.y-p2.y)* (p1.y-p2.y) + (p1.z-p2.z)* (p1.z-p2.z));
}

//Get Points Line:
point lineto(point fp,point p,float length)
{
	point res;
    float L=GetLineLength(fp,p);
    res.x=fp.x+length*(p.x-fp.x)/L;
    res.y=fp.y+length*(p.y-fp.y)/L;
    res.z=fp.z+length*(p.z-fp.z)/L;
    return res;
}
vector<point> GetPointsLine(point origin,point destination)
{
    point t=origin;
    vector<point> coordenates;
	float dst=GetLineLength(origin,destination);
	for (int i=0;i<=dst;i++)
    {
        t=lineto(t,destination,1);
        coordenates.push_back(t);
    }
    return coordenates;
}

point perspective(const point &p,const point &eyepoint)
{
    float   w=1+(p.z/eyepoint.z);
    return {(p.x-eyepoint.x)/w+eyepoint.x,
    (p.y-eyepoint.y)/w+eyepoint.y,
    (p.z-eyepoint.z)/w+eyepoint.z};
}

//Draw a Line:
void DrawLine(HDC WindowHDC,point origin,point destination,COLORREF color=RGB(0,0,255) )
{

    //for convert 3D to 2D we must:
    //have Focal Distance, in these case is 100
    //float FocalDistance =100;
    //2D.X = 3D.X * FocalDistance / 3D.Z
    //2D.Y = 3D.Y * FocalDistance / 3D.Z


    //Getting the Points of a line:
    vector<point> coordenates;

    //origin.z=-origin.z;
    //destination.z=-destination.z;
    coordenates = GetPointsLine(origin,destination);
    point eyepoint={250,150,300};
    //now we draw the line with a color and convert the 3D to 2D:
	for (point LinePoints:coordenates)
    {
    	point p=perspective(LinePoints,eyepoint);
    	//SetPixel(WindowHDC,p.x,p.y,color);

    	std::thread thread_obj(SetPixel, WindowHDC,p.x,p.y,color);
    	thread_obj.join();
    }
}

void DrawRectangle(HDC WindowHDC,point  Top, point Left, point Right, point Bottom,COLORREF color=RGB(255,0,0) )
{

    //for convert 3D to 2D we must:
    //have Focal Distance, in these case is 100
    //2D.X = 3D.X * FocalDistance / 3D.Z
    //2D.Y = 3D.Y * FocalDistance / 3D.Z
    float FocalDistance =100;

    //Getting the Points of a line:
    vector<point> coordenates;

/*    coordenates = GetPointsLine(origin,destination);
    point eyepoint={250,150,300};
    //now we draw the line with a color and convert the 3D to 2D:
	for (point LinePoints:coordenates)
    {
    	point p=Convert3DTO2D(LinePoints); //perspective(LinePoints,eyepoint);
    	SetPixel(WindowHDC,p.x,p.y,color);
    }*/
}

//Draw an Image:
void DrawImage(HDC HDCWindow,point corners[4], HDC HDCOrigin, int PosX, int PosY, int Width, int Height)
{

    POINT ImageCordeners[3];

    //Move Top-Left Corner:
    ImageCordeners[0].x=corners[0].x;
    ImageCordeners[0].y=corners[0].y;

    //Move Top-Right Corner:
    ImageCordeners[1].x=corners[1].x;
    ImageCordeners[1].y=corners[1].y;

    ////Move the  Bottom-Right Corner:
    ImageCordeners[2].x=corners[2].x;
    ImageCordeners[2].y=corners[2].y;

    PlgBlt(HDCWindow,ImageCordeners,HDCOrigin,PosX,PosY,Width,Height,NULL,0,0);
}

//Draw image pixel a pixel:
void DrawImagePoint(HDC HDCDestination,HDC HDCOrigin, point TopLeft,point TopRight,point BottomLeft,point BottomRight)
{
    //Getting the Points of a line:
    vector<point> LeftLine;
    LeftLine = GetPointsLine(TopLeft,BottomLeft);

    vector<point> RgihtLine;
    RgihtLine = GetPointsLine(TopRight,BottomRight);


    for(int PosX=0; PosX<LeftLine.size(); PosX++)
    {
        vector<point> PixelLine;
        PixelLine=GetPointsLine(LeftLine[PosX], RgihtLine[PosX]);

        for (int PosY=0; PosY<PixelLine.size(); PosY++)
        {
            point Point=PixelLine[PosY];

            COLORREF color;
            color=::GetPixel(HDCOrigin,PosY+800,PosX);
            ::SetPixel( HDCDestination,PosY,PosX,color);
        }
    }
}

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());
    point TopLeft={100, 200,0};
    point TopRight={200,200,0};
    point BottomLeft={100,300,0};
    point BottomRight={200,300,0};

    point RotationPoint={250,150,0};//center of rectangle
    angle angles;
    image img("c:\\1595973613452.bmp");


    RECT a;

    a.left=0;
    a.right=800;
    a.top=0;
    a.bottom=800;
	do
    {
        //angles.x+=0.1;
        //TopLeft:
        point TopLeftRotated=TopLeft;//RotationPoints(TopLeft,{angles.x,angles.y,angles.z},RotationPoint);
        //TopRight:
        point TopRightRotated=TopRight;//RotationPoints(TopRight,{angles.x,angles.y,angles.z},RotationPoint);
        //BottomLeft:
        point BottomLeftRotated=BottomLeft;//RotationPoints(BottomLeft,{angles.x,angles.y,angles.z},RotationPoint);
        //BottomRight:
        point BottomRightRotated=BottomRight;//RotationPoints(BottomRight,{angles.x,angles.y,angles.z},RotationPoint);
        img.DrawImagePoint(WindowHDC,TopLeft,TopRight,BottomLeft,BottomRight);



        Sleep(100);

        //FillRect(WindowHDC,&a, CreateSolidBrush(RGB(0,0,0)));
    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));//press escape for exit
    cout<<"Press return to end . . ."<<endl;
    cin.get();
}

eis as opções\comandos no compilador:

-fpermissive
-std=c++0x
-pthread
-Ofast

 

e as librarias adicionadas:

\libgdi32.a

\libgdiplus.a

\libmsimg32.a

 

(a \libmsimg32.a é para usar a função TransparentBlt())

resultado: esse rectangulo é o tamanho da imagem... mas estou a perder as cores?
image.thumb.png.0f0d073390350dd7122580ff395ca88b.png

 

o problema será aqui?

hBitmap= CreateBitmap(Width, Height, 1, 32, pixels);

ou como obtenho as cores?
 

 //Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight, angle angles={0,0,0})
    {
        //Getting the Points of a line:
        vector<point> LeftLine;
        //TopLeft = RotationPoints(TopLeft,angles);
        //TopRight = RotationPoints(TopRight,angles);
        //BottomLeft = RotationPoints(BottomLeft,angles);
        //BottomRight = RotationPoints(BottomRight,angles);
        line LineLeft(TopLeft,BottomLeft);
        LeftLine = LineLeft.GetPointsLine();
        vector<point> RgihtLine;
        line LineRight(TopRight,BottomRight);
        RgihtLine=LineRight.GetPointsLine();


        for(int PosX=0; PosX<LeftLine.size(); PosX++)
        {
            vector<point> PixelLine;
            line LinePixel(LeftLine[PosX], RgihtLine[PosX]);
            PixelLine=LinePixel.GetPointsLine();

            for (int PosY=0; PosY<PixelLine.size(); PosY++)
            {
                point Point=PixelLine[PosY];

                //Get the pixel:
                COLORREF clr;
                BYTE Red = pixels[(PosX*Width+PosY) + 2]; // obtemos Red;
                BYTE Green = pixels[(PosX*Width+PosY) + 1]; // obtemos Green;
                BYTE Blue = pixels[(PosX*Width+PosY) + 0]; // obtemos Blue;
                BYTE Alpha = pixels[(PosX*Width+PosY) + 3]; // obtemos Alpha;
                clr=RGB(Blue, Green,Red);
                ::SetPixel(hdcDestination,PosY,PosX,clr);
            }
        }
    }

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!