Ir ao conteúdo
  • Cadastre-se

C Como otimizar uma função?


Cambalinho

Posts recomendados

ainda estou a testar e parece que tenho mais erros do que pensava 😞
a minha função de obter os pontos de  1 recta 3D(mesmo o Z sendo zero), está me a deixar  doido 😞

depois voltarei com mais noticias

resolvi porque no 'for' deveria ter:

 

PosY<PixelLine.size()-1;

agora estou a obter cores aleatorias.. eis como crio o HBITMAP:

void FromFile(string strFile)
    {
        //Limpar todos os objectos:
        Dispose();

        //Iniciar o GDIPlus:
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

        //Criar 1 imagem GDIPlus:
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();

        //Obter o Graphics da imagem:
        graphic= Graphics::FromImage(this->img);

        //Alterar o vector dos pixels com o tamanho da imagem:
        unsigned int* pixels = (unsigned int*)malloc(Width*Height*sizeof(unsigned int));

        //Criar 1 HDC para desenhar a imagem:
        ImageHDC = CreateCompatibleDC(GetDC(NULL));

        //Criar o HBITMAP com o tamanho e indicar o ponteiro dos pixels:
        hBitmap=CreateBitmap(Width,Height,1,32,pixels);

        //Combinar o HBITMAP com o HDC:
        SelectObject(ImageHDC, hBitmap);

        //obter o HDC do HBITMAP para desenhar a imagem do GDIPlus:
        Graphics *g;
        g=Graphics::FromHDC(ImageHDC);
        g->DrawImage(img,0,0);

    }

eis 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})
    {
        //Obter os pontos das 2 linhas verticais:
        //Getting the Points of a line:
        vector<point> LeftLine;
        LeftLine = GetPointsLine(TopLeft,BottomLeft);

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



        int pixelposition=0;
        for(int PosX=0; PosX<LeftLine.size()-1; PosX++)
        {
            //Calcular os pontos da linha horizontal usando os pontos das linha verticais
            vector<point> PixelLine;
            PixelLine=GetPointsLine(LeftLine[PosX], RgihtLine[PosX]);

            for (int PosY=0; PosY<PixelLine.size()-1; PosY++)
            {
                //Obter o ponto da recto Horizontal:
                point Point=PixelLine[PosY];

                //Obter a cor do pixel:
                COLORREF clr;
                clr=pixels[pixelposition];

                //se os pontos são 3D, temos de usar a perspectiva
                point eyepoint={250,150,300};
                Point = perspective(Point,eyepoint);

                //Imprimir o pixel no Destino do HDC:
                ::SetPixel(hdcDestination,PosX,PosY,clr);
                pixelposition++;
            }
            //pixelposition++;
        }
    }

resultado:

image.thumb.png.cd05466e2f026c7f216cb40251d3bae6.png

 

o que estou a fazer errado para obter e usar os pixels?

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

Notei, mas mais tarde,  1 erro:

BYTE Red = pixels[(PosX*Width+PosY) + 2]; // obtemos Red;

Deveria ser:

BYTE Red =    *  pixels[(PosX*Width+PosY) + 2]; // obtemos Red;

O outro problema é que os 4 pontos podem ser uma figura maior ou menor do que a imagem.  Logo tenho de actualizar isso e permitir usar uma cor transparente. 

Muito obrigado 

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

@Cambalinho     oi , tudo bem ?  , você postou o mesmo código ,  com um arquivo "main.c" e outro "imagem.h"  e não sei como compilar para que funcionem , você poderia me postar um único código de seu programa , juntando esses arquivos em um só  ?  por favor , obrigado desde já .

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

Em 14/02/2022 às 13:55, Cambalinho disse:

Otimizar,  penso, é evitar duplicar o código e tentar evitar muito consumo do CPU.

 

Bem, depende. Primeiro você deveria especificar o aspecto que gostaria de otimizar e a performance não é o único dos tantos que existem.

Mas considerando que seja isto, otimizar performance, definitivamente, não é sobre evitar o consumo da CPU, pelo contrário, é garantir que a CPU esteja sempre cheia de serviço útil a ser feito. A CPU tá sempre executando algo mesmo que a instrução seja fazer nada. Por exemplo, se ela precisa acessar a memória RAM pra ler um determinado valor, pelo fato da RAM funcionar numa frequência muito inferior, a CPU precisa ficar centenas, talvez milhares, de ciclos fazendo nada até que o valor tenha sido carregado da RAM pra memória cache. Caso ela precise fazer isso frequentemente, temos então uma CPU que passa boa parte do tempo fazendo nada, esperando uma resposta da memória RAM, ou seja, baixa performance.

Você não deve otimizar às cegas supondo o que seria o problema. Primeiro você deve executar o programa num profiler e o relatório vai apontar as partes do código que estão engasgando. Apenas então você pode montar uma estratégia de otimização. Depois dessa etapa, sabendo qual é o problema especifico, geralmente, e no caso de C++, algumas práticas pra extrair performance são:

- Evite alocar memória frequentemente com new e delete. São operações muito custosas e que, por vezes, podem ser substituídas pela stack. Ou, alternativamente, faça uma alocação grande no inicio, gerencie esse recurso durante o curso do programa e libere apenas ao final.

- Quanto mais alocação dinâmica fizer mais fragmentada ficará a memória e, portanto, mais custosas serão as próximas alocações.

- Favoreça malloc (ou calloc e realloc) ao invés de new. Chamar new implica alocar memória na heap mais uma chamada do construtor enquanto malloc & cia apenas alocam memória (ainda assim custosamente).

- Favoreça free ao invés de delete pela mesma razão: delete implica uma chamada do destrutor antes de liberar a memória enquanto free apenas libera (ainda assim custosamente também).

- Evite uso exagerado de classes por que você vai findar criando "bolhas" na memória nas quais os dados, que deveriam estar alinhados pra acesso sequencial e rápido, ficam isolados e a CPU perde boa parte do tempo pulando de um local pro outro (cache miss é extremamente custoso).
- Favoreça uma struct de arrays ao invés de um array de structs. E favoreça também acessar dados sequencialmente de maneira que a CPU possa predizer os próximos elementos que ela vai precisar.

- Evite dereferenciar ponteiros por que o próximo local apontado pelo ponteiro certamente não será aquele que já estaria disponível na cache da CPU, forçando-a a voltar a acessar a memória RAM (muito lento).

- Evite todas as situações que possam estar induzido o compilador a criar objetos temporários, principalmente, se são instâncias de classes com construtores e destrutores pesados.

- Tente determinar (com o profiler) quais as funções mais quentes e então, se possível, redesenhá-las pra versões inline.

- Considere desenhar a manipulação dos dados em sequências de blocos de, digamos, 64 Kb, ou qualquer que seja o tamanho da cache da maquina que está a usar, e assim você pode usufruir de registros mais largos com SIMD pra operações aritméticas. Dependendo do nível de otimização do compilador, ele pode já estar a fazer isto por você mas você pode programar assim pra impor um comportamento ideal independente do compilador.

 

Há muitas dicas mais mas o importante mesmo é, antes de tudo, fazer um benchmark com um bom profiler pra determinar a causa da lentidão do programa.
 

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

como prometido e sim mudei algumas coisas, mas teste alguns erros do meu codigo:

#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;

class GDI_Plus
{
public:
	GDI_Plus()
	{
		Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, nullptr);
	}
	~GDI_Plus()
	{
		Gdiplus::GdiplusShutdown(m_gdiplusToken);
	}
private:
	ULONG_PTR m_gdiplusToken = 0;
	Gdiplus::GdiplusStartupInput gdiplusStartupInput = {0};
};

struct Pixel
{
  BYTE red,
          green,
          blue,
          alpha;
};

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

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

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

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};
}

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);
	point eyepoint={250,150,300};
	for (int i=0;i<=dst;i++)
    {
        t=lineto(t,destination,1);
        //t = perspective(t,eyepoint);
        coordenates.push_back(t);
    }
    return coordenates;
}

//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;
}

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;
}

void GetPixelsFromHDC(HDC Destination, int *pixels)
{

    HBITMAP hBitmap = reinterpret_cast<HBITMAP>(GetCurrentObject(Destination, OBJ_BITMAP));
    DIBSECTION dibs;
    ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
    BITMAPINFO bitinfo;
    ::GetObject(hBitmap, sizeof(BITMAPINFO), &bitinfo);
    pixels = (unsigned int*)malloc(dibs.dsBmih.biWidth*dibs.dsBmih.biHeight*sizeof(unsigned int));
    ::GetDIBits(Destination, hBitmap,0,0,&pixels,&bitinfo,dibs.dsBmih.biClrUsed);
}

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)};
}


//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);
        }
    }
}

class image
{
    public:

    ULONG_PTR m_gdiplusToken=NULL;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Graphics *graphic=nullptr;
    Gdiplus::Bitmap *img;
    Pixel *pixel;
    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()
    {
        GDI_Plus _ ;
        //nothing:

    }

    image(int SizeWidth, int SizeHeight)
    {
        GDI_Plus _ ;
        //New(SizeWidth, SizeHeight);

    }

    image(string strFile)
    {
        GDI_Plus _ ;
        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();
        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:

        //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)
    {
        //clean all objects.. here i must update it, but i need test an object before delete it:
        Dispose();



        //Create a GDIPlus image:
        img =new Bitmap(towstring(strFile).c_str());
        Width=img->GetWidth();
        Height=img->GetHeight();

        //Get Graphics from image:
        graphic= Graphics::FromImage(img);
        Gdiplus::Rect rect(0,0, img->GetWidth(), img->GetHeight());
        Gdiplus::BitmapData data;
        auto status = img->LockBits(&rect, Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &data); // 24 bit jpeg
        pixel = static_cast<Pixel*>(data.Scan0);
        img->UnlockBits(&data);
        int numPixels = img->GetWidth() * img->GetHeight();


        //Create the HDC for draw the image:
        ImageHDC = CreateCompatibleDC(GetDC(NULL));

        //Create the HBITMAP using the image size and pixels pointer:
        hBitmap=CreateBitmap(Width,Height,1,32,NULL);

        //Combine the HBITMAP the HDC:
        SelectObject(ImageHDC, hBitmap);

        //Get the Graphics from HDC and draw the image on HDC:
        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})
    {
        //Obter os pontos das 2 linhas verticais:
        //Getting the Points of a line:
        vector<point> LeftLine;
        LeftLine = GetPointsLine(TopLeft,BottomLeft);

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

        int pixelposition=0;
        int PosX=0;
        int PosY=0;
        int *DestinationPixels;
        GetPixelsFromHDC(hdcDestination, DestinationPixels);
        for( PosX=0; PosX<LeftLine.size()-1; PosX++)
        {
            //Calcular os pontos da linha horizontal usando os pontos das linha verticais
            vector<point> PixelLine;
            PixelLine=GetPointsLine(LeftLine[PosX], RgihtLine[PosX]);
            for ( PosY=0; PosY<PixelLine.size()-1; PosY++)
            {
                //Obter o ponto da recto Horizontal:
                point Point=PixelLine[PosY];

                //Obter a cor do pixel:
                COLORREF clr;
                byte r =pixel->red;
                byte g = pixel->green;
                byte b=pixel->blue;
                byte a=pixel->alpha;
                clr=RGB(b,g,r) ;


                //se os pontos são 3D, temos de usar a perspectiva
                point eyepoint={250,150,300};
                Point = perspective(Point,eyepoint);

                //Imprimir o pixel no Destino do HDC:
                DestinationPixels=clr;
                //::SetPixel(hdcDestination,PosY,PosX,clr);
                ++pixel;
                ++pixelposition;
                ++DestinationPixels;
            }
        }
        //in these case the pixelposition, is the last pixel position:
        for (int i=pixelposition; i!=0; i--)
        {
            --pixel;
            --DestinationPixels;
        }
    }
};

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());
    image img("c:\\1595973613452.bmp");

    point TopLeft={0, 0,0};
    point TopRight={img.Width,0,0};
    point BottomLeft={0,img.Height,0};
    point BottomRight={img.Width,img.Height,0};
    point RotationPoint={img.Width/2,img.Height/2,0};

    angle d;

	do
    {
        d.y+=1;
        //TopLeft:
        point TopLeftRotated=RotationPoints2(TopLeft,d,RotationPoint);
        //TopRight:
        point TopRightRotated=RotationPoints2(TopRight,d,RotationPoint);
        //BottomLeft:
        point BottomLeftRotated=RotationPoints2(BottomLeft,d,RotationPoint);
        //BottomRight:
        point BottomRightRotated=RotationPoints2(BottomRight,d,RotationPoint);

        RECT f={0,0,1000,1000};
        FillRect(WindowHDC,&f,(HBRUSH)(RGB(255,255,255)));
        img.DrawImagePoint(WindowHDC,TopLeftRotated,TopRightRotated,BottomLeftRotated,BottomRightRotated);


        Sleep(100);

    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));//press escape for exit*/

    cout<<"Press return to end . . ."<<endl;
    cin.get();
}

está tudo num ficheiro.

agora estou a testar para evitar o 'SetPixel()', mas estou sem resultados. talvez o erro seja na função 'GetPixelsFromHDC()', mas não sei.

aceito mais dicas 😞

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

@Cambalinho ptr++ faz com que o ponteiro aponte pra posição seguinte na memória.

Se tem um vetor dinâmico como aquele tal `pixels`, pode indexar para acessar cada um dos elementos.

 

39 minutos atrás, Cambalinho disse:

NomeDoPonteiro=valor

Se `valor` for um endereço, então ok.

39 minutos atrás, Cambalinho disse:

(penso que deveria ser:
*NomeDoPonteiro=Valor

Daí sim, altera o valor apontado pelo ponteiro.

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

void GetPixelsFromHDC(HDC Destination, int *pixels)
{

    HBITMAP hBitmap = reinterpret_cast<HBITMAP>(GetCurrentObject(Destination, OBJ_BITMAP));
    DIBSECTION dibs;
    ::GetObject(hBitmap, sizeof(DIBSECTION), &dibs);
    BITMAPINFO bitinfo;
    ::GetObject(hBitmap, sizeof(BITMAPINFO), &bitinfo);
    pixels = (unsigned int*)malloc(dibs.dsBmih.biWidth*dibs.dsBmih.biHeight*sizeof(unsigned int));
    ::GetDIBits(Destination, hBitmap,0,dibs.dsBmih.biHeight,&pixels,&bitinfo,dibs.dsBmih.biClrUsed);
}

 

//Draw image pixel a pixel:
    void DrawImagePoint(HDC hdcDestination,point TopLeft,point TopRight,point BottomLeft,point BottomRight)
    {
        point LeftLineOrigin=TopLeft;
        point LeftLineDestination=BottomLeft;

        point RightLineOrigin=TopRight;
        point RightLineDestination=BottomRight;

        vector<point> LeftLineDots=GetPointsLine(TopLeft,BottomLeft);
        vector<point> RightLineDots=GetPointsLine(TopRight, BottomRight);
        COLORREF color;
        int pixelposition=0;
        int *pixelspointer;
        GetPixelsFromHDC(hdcDestination,pixelspointer);
        //now we draw the line with a color and convert the 3D to 2D:
        for (int Y=0; Y<LeftLineDots.size(); Y++)
        {
            int X=0;
            point CenterLineOrigin=LeftLineDots[Y];
            point CenterLineDestination=RightLineDots[Y];
            vector<point> CenterLine=GetPointsLine(CenterLineOrigin,CenterLineDestination);
            for(point points:CenterLine)
            {
                color =RGB(pixel->blue, pixel->green, pixel->red);
                int pos=points.x*points.y;
                pixelspointer[pos]=color;
                //SetPixelV(hdcDestination,points.x,points.y, color);
                ++pixelposition;
                ++pixel;
                //++pixelspointer;

            }

        }
        //in these case the pixelposition, is the last pixel position:
        for (int i=pixelposition; i!=0; i--)
        {
            --pixel;
            --pixelspointer;
        }
    }

na execução tenho 1 erro:

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

penso que erro vem daqui:

pixelspointer[pos]=color;

porque já converti em comentário...

o que estou a fazer de errado?

uma questão: eu não criei 1 HBITMAP para a consola... será que não existe algum?

  • 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...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!