-
Posts
902 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que Cambalinho postou
-
C++ Matemática: como se move 1 ponto no Espaço?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
isso era simples, mas não funciona.. tive de criar estas funções: void LineMoveFront(int &X0, int &Y0, int &Z0,int &X1, int &Y1, int &Z1, int Speed) { float DX = X1 - X0; float DY = Y1 - Y0; float DZ = Z1 - Z0; float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2)); float XStep = DX / LineDistance; float YStep = DY / LineDistance; float ZStep = DZ / LineDistance; X0+=round(XStep*Speed); Y0+=round(YStep*Speed); Z0+=round(ZStep*Speed); X1+=round(XStep*Speed); Y1+=round(YStep*Speed); Z1+=round(ZStep*Speed); } void LineMoveBack(int &X0, int &Y0, int &Z0,int &X1, int &Y1, int &Z1, int Speed=1) { float DX = X1 - X0; float DY = Y1 - Y0; float DZ = Z1 - Z0; float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2)); float XStep = DX / LineDistance; float YStep = DY / LineDistance; float ZStep = DZ / LineDistance; X0-=round(XStep*Speed); Y0-=round(YStep*Speed); Z0-=round(ZStep*Speed); X1-=round(XStep*Speed); Y1-=round(YStep*Speed); Z1-=round(ZStep*Speed); } int main() { HDC HDCConsole = GetConsoleHDC(); RECT rec; GetClientRect(GetConsoleWindow(),&rec); int Speed=1; int LinePositions[6] = {100,100,0,900,100,500}; do { DrawLine3D(HDCConsole,LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5]); Sleep(50); FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0))); Speed=1; if((GetKeyState(VK_RSHIFT) & 0x8000)) { Speed=10; } if((GetKeyState(VK_UP) & 0x8000)) { LineMoveBack(LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5], Speed); } if((GetKeyState(VK_DOWN) & 0x8000)) { LineMoveFront(LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5], Speed); } }while(!(GetKeyState(VK_ESCAPE) & 0x8000)); cout << "Draw ended!!!"; cin.get(); return 0; } é mais complexo mas faz o que queria... a linha se move com a mesma direção\angulo -
C++ Matemática: como se move 1 ponto no Espaço?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
eu estou a tentar mover a figura para a frente e para trás.... mas, algumas vezes, a figura se move para a direita ou esquerda..... algo está mal neste codigo: void DrawLine3D(HDC Destination, int X0, int Y0, int Z0, int X1, int Y1, int Z1, COLORREF LineColor = RGB(255,0,0)) { //Avoiding division by zero: if(Z0==0) Z0=1; if(Z1==0) Z1=1; //Getting Line Distance(float results): float DX = X1 - X0; float DY = Y1 - Y0; float DZ = Z1 - Z0; float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2)); //Getting the Steps incrementation(float results): float XSteps = DX/LineDistance; float YSteps = DY/LineDistance; float ZSteps = DZ/LineDistance; //Draw Line using the Steps\ Incrementation: float X = X0; float Y = Y0; float Z = Z0; int OldPosX=X0; int OldPosY=Y0; for(int i=0; i<LineDistance; i++) { //For every steps we calculate the perspective: float Perspective = 300/(300+Z); //The 3D to 2D convertion(i use 300 of eye distance, but we can change it): int PosX = trunc(X*Perspective); int PosY = trunc(Y*Perspective); //if(PosX==OldPosX && PosY==OldPosY) continue; OldPosX=PosX; OldPosY=PosY; //Draw the pixel: if(Z>0) SetPixel(Destination,PosX,PosY,LineColor); //Increment steps(integer results): X+=XSteps; Y+=YSteps; Z+=ZSteps; } } //............... int Front=0; int Speed=1; do { DrawLine3D(HDCConsole,100-Front,100,0-Front, 900-Front,100,500-Front); DrawLine3D(HDCConsole,100-Front,100,0-Front, 100-Front,400,0-Front); DrawLine3D(HDCConsole,900-Front,100,500-Front, 900-Front,400,500-Front); DrawLine3D(HDCConsole,100-Front,400,0-Front, 900-Front,400,500-Front); Sleep(50); FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0))); Speed=1; if((GetKeyState(VK_RSHIFT) & 0x8000)) { Speed=10; } if((GetKeyState(VK_UP) & 0x8000)) { Front+=Speed; } if((GetKeyState(VK_DOWN) & 0x8000)) { Front-=Speed; } }while(!(GetKeyState(VK_ESCAPE) & 0x8000)); sim em algumas coordenadas a figura se move para a direita e não, só, para a frente e para trás -
C++ Matemática: como se move 1 ponto no Espaço?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
isso eu sei.. o ecrã só usa X e Y.. mas falo em 3D... e isso é que me está a fazer confusão.. o que me baralha mesmo muito é o movimento Z. hás vezes consigo o calculo correto e outras vezes não consigo -
Em Matemática, ainda fico confuso, como se move 1 ponto em Z? exemplo: Movimento = 1 A(100, 100, 0) tenho de fazer: A(100 + Movimento, 100, 0 + Movimento)? ou A(100, 100, 0 + Movimento)? eu já fiz vários códigos, mas muitas das vezes falho aqui.
-
eu tenho drivers para 1 portátil\laptop. como posso criar 1 Driver Pack a partir dos instaladores dos drivers? penso que o formato fica *.7zip.
-
C++ C++: O que é Anti-aliased e para que serve?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
muito obrigado... vou aguardar -
C++ C++: O que é Anti-aliased e para que serve?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
em toda a área: eu ainda não entendi como funciona os cálculos para calcular os pontos da recta... mas pode ser por isso mesmo que tenho esses pixels pretos dentro do vermelho e eu não sei como os testar -
C++ C++: O que é Anti-aliased e para que serve?
Cambalinho respondeu ao tópico de Cambalinho em C/C#/C++
eis a minha função de http://members.chello.at/easyfilter/bresenham.html struct point { float x,y,z; } ; vector<point> GetLinePoints(point Origin, point Destination) { vector<point> LinePoints; point LinePoint; int dx = abs(Destination.x-Origin.x), sx = Origin.x<Destination.x ? 1 : -1; int dy = abs(Destination.y-Origin.y), sy = Origin.y<Destination.y ? 1 : -1; int dz = abs(Destination.z-Origin.z), sz = Origin.z<Destination.z ? 1 : -1; int dm =std::max( { dx, dy, dz } ), i = dm; /* maximum difference */ Destination.x = Destination.y = Destination.z = dm/2; /* error offset */ do { Destination.x -= dx; if (Destination.x < 0) { Destination.x += dm; Origin.x += sx; } Destination.y -= dy; if (Destination.y < 0) { Destination.y += dm; Origin.y += sy; } Destination.z -= dz; if (Destination.z < 0) { Destination.z += dm; Origin.z += sz; } LinePoint.x=Origin.x; LinePoint.y=Origin.y; LinePoint.z=Origin.z; LinePoints.push_back(LinePoint); i--; }while(i >=0); return LinePoints; } eis o resultado: alguns pixels(sim era para ser vermelho) não são imprimidos ou tem coordenadas erradas -
C++: O que é Anti-aliased e para que serve? Eu tenho outra função para desenhar uma linha, mas, dependendo da rotação, posso perder alguns pontos da linha. Eu penso que não é perder, mas pode ir para outro pixel que não é o correcto. Será que fazer o Anti-aliased, é tentar corrigir esse erro?
-
Tem só HDC. O melhor é fazer um HBITMAP com HDC para fazer o resultado pixel a pixel, como um buffer, e depois usar o BitBlt() para desenhar no HDC da janela.
-
pergunta chave: a janela tem HBITMAP ou só HDC?
-
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?
-
Mas se eu quiser uma posição, tipo 15, como faço para ver e alterar o valor?
-
me corrija 1 coisa para testar: normalmente fazemos: ++NomeDoPonteiro; NomeDoPonteiro=valor (penso que deveria ser: *NomeDoPonteiro=Valor ou seja usamos '*' para obter\alterar o valor) mas imagine que quero 1 posição do ponteiro, como o faço?
-
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
-
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
-
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: o que estou a fazer errado para obter e usar os pixels?
-
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? 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); } } }
-
@devair1010 uso CodeBlocks com GNU/GCC. Mais logo posto o código todinho
-
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?
-
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
-
por favor verifique o post anterior que fiz\actualizei
-
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
-
@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?
-
você utiliza um loop com step de 4 e: (Y*width+X) + 2 : obtemos Red; (Y*width+X) + 1 : obtemos Green; (Y*width+X) + 0 : obtemos Blue; (Y*width+X) + 3 : obtemos Alpha; certo?
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