Is there an API function in the lines of BitBlt or StretchBlt for rotating
a bitmap by 90º? In other words, it must transpose the matrix of pixel
values and thereafter do a horizontal or vertical flip, depending on
whether the rotation is CW or CCW.
Printable View
Is there an API function in the lines of BitBlt or StretchBlt for rotating
a bitmap by 90º? In other words, it must transpose the matrix of pixel
values and thereafter do a horizontal or vertical flip, depending on
whether the rotation is CW or CCW.
There isnt a specific api function more a use of thema nd coding, have you had a search? there is a few example out there.
Doe sthis help by NoteMe?
http://www.vbforums.com/showpost.php...88&postcount=4
Here is the actual thread
http://www.vbforums.com/showthread.p...t=rotate+image
use plgblt
it does not automatically rotate it but it can be used for rotating
I know this thread, I used NoteMe's code when I had to implement rotations by any degree. For 90º rotations however I hoped there was a much faster function, as the one notquitehere188 has suggested.Quote:
Originally Posted by Pino
I know you must apply a flip to complete the rotation, but the simple transpose operation is not working for me:Quote:
Originally Posted by notquitehere188
It does just nothing. Can it be used with the same source and destination?VB Code:
Pt(0).x = 0 Pt(0).y = 0 Pt(1).x = Picture2.ScaleHeight Pt(1).y = 0 Pt(2).x = 0 Pt(2).y = Picture2.ScaleWidth PlgBlt Picture2.hdc, Pt(0), Picture2.hdc, 0, 0, Picture2.ScaleWidth, _ Picture2.ScaleHeight, ByVal 0&, ByVal 0&, ByVal 0&
bump
You can flip the picture using the paintpicture method by supplying a negative value for either the destination height or width
Flipping is not the problem, it's transposing, i.e. from an original matrix A where pixel values are stored with NRow rows and NCol columns, a new matrix B must be created with NCol rows and NRow columns such that:Quote:
Originally Posted by moeur
B(i,j) = A(j,i)
for i=1, 2, ..., NRows and j=1, 2, ..., NCols
If that can be done with a single call to PlgBlt rather than using loops then a 90º rotation is quite straighforward (and I would imagine faster) as it is a combination of a flip followed by a transposition. The problem is I can't get PlgBlt working.
All right, I'm ready to do it with 2 nested loops. But for large images, even with GetPixel and SetPixel this could be kind of slow, so I thought I'd do it with a VC++ DLL, as some of you folks have recently taught me the basic steps.
The one question I need an answer to before I get down to business is, how can I pass a picturebox as an argument to the procedure in the DLL?
OK, I've solved that. I've made my sub in a C dll and it works nicely. However I've used SetPixel and GetPixel and this doesn't make it fast enough for large pictureboxes.Quote:
Originally Posted by Me
My 2 questions to the C experts:
- Is there really anything to be gained by doing 2 nested loops with SetPixels & GetPixels in VC++ rather than in VB?
- Is it worth using DIB functions in the VC++ DLL to speed it up?
Rotation by 90 degree should be easy to do in C++, I can do it for yu but right now i'm at work (just starting).
SetPixel and GetPixel are VERY, VERY.... VERY :) slow... even though it's API...
The fastest way to do it is to get the actual bitmap data, and work with the bytes, but you have to understand the bitmap structure for that, it's actually easy...
Actually, if you do it this way, even in VB will be a significant improvement compared to SetPixel and GetPixel.
If I forget to do it, remind me in about 10 hours
Well, in about 10 hours I'll probably be in bed counting bytes to catch some sleep... so I remind you now...Quote:
Originally Posted by CVMichael
My app reads a large file (ca. 10 Mb) and then plots the contents in a bitmap. I've implemented a part of the code in VC++ to make it faster -and it really is.
The actual plotting is handled by SetDIBitsToDevice, which is perhaps what you had in mind. However, this part is in VB (I'm using somene else's code that I found in the forum) so,
(1) I'd like to know if it can improve in terms of speed by converting it to VC++ and
(2) I'm not sure I'm able to transpose (rotation = flip + transposition) the array of bytes:
MyByteArray(NBytes)
where the overall number of bytes is
NBytes = Rows * (3 * Cols + DBytes)
DBytes is the number of dummy bytes at the end of each row (so all rows are divisible by 4) like
RGBR GBRG B000
RGBR GBRG B000
RGBR GBRG B000
I downloaded this from my home computer...
You have to put it in a module.
Use the GetBitmapData to get the bitmap as an array, so you can manipulate the data, and SetBitmapData to put the data back in the PictureBox.
For the SetBitmapData, the value param is a long, so you will have to use the VarPtr(YourArray(0)) function to get the array pointer.
The functions works in 24 bits, so it does not matter how many bits per pixel your screen resolution has, it will always convert to 24 bits. And SetBitmapData function it's expecting that you pass a 24 bit bitmap data to it.
You will need these functions even when I'll make the C++ rotation, cuz you need to pass the pointer to the data to the DLL.
VB Code:
Option Explicit Public Const BI_RGB = 0& Public Const BI_RLE4 = 2& Public Const BI_RLE8 = 1& Public Const DIB_RGB_COLORS = 0 ' color table in RGBs Public Const DIB_PAL_COLORS = 1 ' color table in palette indices Public Const DIB_PAL_INDICES = 2 ' No color table indices into surf palette Public Const DIB_PAL_PHYSINDICES = 2 ' No color table indices into surf palette Public Const DIB_PAL_LOGINDICES = 4 ' No color table indices into DC palette Public Const SRCCOPY = &HCC0020 ' (DWORD) dest = source Public Type SAFEARRAYBOUND cElements As Long lLbound As Long End Type Public Type SAFEARRAY2D cDims As Integer fFeatures As Integer cbElements As Long cLocks As Long pvData As Long Bounds(0 To 1) As SAFEARRAYBOUND End Type Public Type BITMAPINFOHEADER '40 bytes biSize As Long biWidth As Long biHeight As Long biPlanes As Integer biBitCount As Integer biCompression As Long biSizeImage As Long biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As Long biClrImportant As Long End Type Public Type BITMAPINFO bmiHeader As BITMAPINFOHEADER bmiColors As Long ' RGBQUAD End Type Public Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Public Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Long, pBitmapInfo As BITMAPINFO, ByVal un As Long, lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long Public Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long Public Declare Function GetObjectType Lib "gdi32" (ByVal hgdiobj As Long) As Long Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long Public Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Public Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Public Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpbi As BITMAPINFO, ByVal wUsage As Long) As Long Public Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpbi As BITMAPINFO, ByVal wUsage As Long) As Long Public Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long Public Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long Public Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Public Function GetBitmapData(hdc As Long, Width As Long, Height As Long, value() As Byte, Optional ByVal ReSize As Double = 1) As Boolean Dim bi As BITMAPINFO, mhDC As Long, bitsPtr As Long, hDIB As Long Dim bDibFrom() As Byte, Size As Long, old_bmp As Long, Ret As Long Dim RWidth As Integer, RHeight As Integer Dim tSAFrom As SAFEARRAY2D mhDC = CreateCompatibleDC(0) If mhDC <> 0 Then With bi.bmiHeader .biSize = Len(bi.bmiHeader) If ReSize <> 1 Then RWidth = Width * ReSize .biWidth = RWidth RHeight = Height * ReSize .biHeight = RHeight Else .biWidth = Width .biHeight = Height End If .biPlanes = 1 .biBitCount = 24 .biCompression = BI_RGB .biSizeImage = BytesPerScanLine(.biWidth, .biBitCount) * .biHeight End With hDIB = CreateDIBSection(mhDC, bi, DIB_RGB_COLORS, bitsPtr, 0, 0) If hDIB <> 0 Then old_bmp = SelectObject(mhDC, hDIB) If ReSize <> 1 Then Ret = StretchBlt(mhDC, 0, 0, Width * ReSize, Height * ReSize, hdc, 0, 0, Width, Height, SRCCOPY) Else Ret = BitBlt(mhDC, 0, 0, Width, Height, hdc, 0, 0, SRCCOPY) End If Else DeleteDC mhDC Exit Function End If End If Size = bi.bmiHeader.biSizeImage If (Size > 0) Then ReDim value(Size - 1) With tSAFrom .cbElements = 1 .cDims = 2 .Bounds(0).lLbound = 0 .Bounds(0).cElements = bi.bmiHeader.biHeight .Bounds(1).lLbound = 0 .Bounds(1).cElements = BytesPerScanLine(bi.bmiHeader.biWidth, bi.bmiHeader.biBitCount) .pvData = bitsPtr End With CopyMemory ByVal VarPtrArray(bDibFrom()), VarPtr(tSAFrom), 4 CopyMemory value(0), bDibFrom(0, 0), Size 'Clear the temporary array descriptor, This is necessary under NT4. CopyMemory ByVal VarPtrArray(bDibFrom), 0&, 4 End If DeleteObject hDIB SelectObject mhDC, old_bmp DeleteDC mhDC GetBitmapData = True End Function Public Function SetBitmapData(ByVal hdc As Long, ByVal Width As Long, ByVal Height As Long, ByVal value As Long, Optional ByVal ReSize As Double = 1) As Boolean Dim bi As BITMAPINFO, mhDC As Long, bitsPtr As Long, hDIB As Long Dim bDibFrom() As Byte, old_bmp As Long, Ret As Long mhDC = CreateCompatibleDC(0) If mhDC <> 0 Then With bi.bmiHeader .biSize = Len(bi.bmiHeader) .biWidth = Width .biHeight = Height .biPlanes = 1 .biBitCount = 24 .biCompression = BI_RGB .biSizeImage = BytesPerScanLine(.biWidth, .biBitCount) * .biHeight End With hDIB = CreateDIBSection(mhDC, bi, DIB_RGB_COLORS, bitsPtr, 0, 0) If hDIB <> 0 Then old_bmp = SelectObject(mhDC, hDIB) Ret = SetDIBits(mhDC, hDIB, 0, bi.bmiHeader.biHeight, ByVal value, bi, DIB_RGB_COLORS) If ReSize <> 1 Then Ret = StretchBlt(hdc, 0, 0, Width * ReSize, Height * ReSize, mhDC, 0, 0, Width, Height, SRCCOPY) Else Ret = BitBlt(hdc, 0, 0, Width, Height, mhDC, 0, 0, SRCCOPY) End If Else DeleteDC mhDC Exit Function End If End If DeleteObject hDIB SelectObject mhDC, old_bmp DeleteDC mhDC SetBitmapData = Ret > 0 End Function Public Function BytesPerScanLine(Width As Long, BitCount As Integer) As Long BytesPerScanLine = (Width * BitCount) If (BytesPerScanLine Mod 32 > 0) Then BytesPerScanLine = BytesPerScanLine + 32 - (BytesPerScanLine Mod 32) BytesPerScanLine = BytesPerScanLine \ 8 End Function
Using the functions above, I managed to write the following code, but It does not seem very fast (when it comes to big pictures).
Is this code any faster than what you have now ?
VB Code:
Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As Long Private Sub Form_Load() Dim StartTick As Long Picture1.AutoRedraw = True Picture1.Picture = LoadPicture(App.Path & "\Test.jpg") StartTick = GetTickCount RotatePic Picture1, Picture2 Debug.Print "Time: " & GetTickCount - StartTick End Sub Private Sub RotatePic(FromPic As PictureBox, ToPic As PictureBox) Dim BitData() As Byte, DestBitData() As Byte Dim X As Long, Y As Long, FromPos As Long, ToPos As Long Dim NewSize As Long, BpslFrom As Long, BpslTo As Long FromPic.ScaleMode = vbPixels GetBitmapData FromPic.hdc, FromPic.ScaleWidth, FromPic.ScaleHeight, BitData ' reverse width & height NewSize = FromPic.ScaleWidth * BytesPerScanLine(FromPic.ScaleHeight, 24) ReDim DestBitData(NewSize - 1) BpslFrom = BytesPerScanLine(FromPic.ScaleWidth, 24) BpslTo = BytesPerScanLine(FromPic.ScaleHeight, 24) For Y = 0 To FromPic.ScaleHeight - 1 FromPos = Y * BpslFrom For X = 0 To (FromPic.ScaleWidth - 1) * 3 Step 3 ToPos = (X \ 3) * BpslTo + Y * 3 DestBitData(ToPos + 0) = BitData(FromPos + X + 0) DestBitData(ToPos + 1) = BitData(FromPos + X + 1) DestBitData(ToPos + 2) = BitData(FromPos + X + 2) Next X Next Y ToPic.AutoRedraw = True SetBitmapData ToPic.hdc, FromPic.ScaleHeight, FromPic.ScaleWidth, VarPtr(DestBitData(0)) End Sub
Well, it's quite acceptable, certainly much faster than my Set/Get-Pixels. Now I'll have to study your code in detail and see how it can be adapted into my app. Probably I'm gonna need more help so stand by!!!Quote:
Originally Posted by CVMichael
It could just be the math thats making it slow. Porting it to C++ might add that little bit of speed you are looking for.
I will, but first I've got to check my old C books as I've sort of forgotten all about structures and I anticipate I'll have to use some.Quote:
Originally Posted by chemicalNova
You don't have to use any structures, just use a pointer of char array. Everything is pointers in C/C++ ... If you learn to master pointers in C/C++, you can do pretty cool stuff.
I did not have time to convert it to C++ yesterday, I hope I will have time today after work...
It should not be that difficult. Actually that's why I did it in VB first, cuz I can test easier in VB, and then when it's working properly, I was planning to convert it, but did not get to it.
Also, can you tell me what is the difference in time, like how long did your function take, and how long did mine. Then when I finish the C++ one, to see the final time, and the total difference (just for reference, to see how long each method took)
How about the BITMAPINFO type and all that stuff? Is that implicitly declared in windows.h or any other header file?Quote:
Originally Posted by CVMichael
Don't convert that, it's too difficult, and it won't save much time.
GetBitmapData + SetBitmapData, together they take 30 ms on my computer, if you do it C++ it won't save much time, just convert the 2 for loops in the RotatePic function, that's it...
Loops are slow in VB, that's what you have to convert. There are no loops in GetBitmapData and SetBitmapData ,only API functions, that's why you won't get it much faster by converting to C++.
All right, then that'll be much much easier.Quote:
Originally Posted by CVMichael
I'll let you know about the timing, hopefully tomorrow. Thanks a lot.
Now I come to think of it, your code makes use of a few DIB API functions. I understand these result (sometimes?) in vertically inverted images.
Yea, you are right. I think a bitmap is saved inverted in the bmp file, but I think in memory is stored properly (i.e, pos x = 0, y = 0, is pos 0 in the buffer). I did not do any serious bitmap programming for more than a year, I might be wrong...
Hehe, what a stupid mistake... I forgot to add "Step 3" to the For Loop, line:
Now it takes half the time in VB...VB Code:
For X = 0 To (FromPic.ScaleWidth - 1) * 3 [b]Step 3[/b]
I also edited the previous post and added "Step 3" to that line...
[edit] Is it rotating properly ??
It seems that it rotates and flips at the same time, I don't think it should do that ?
Before I was testing with a picture that looked almost the same even if you rotate, but I just tested with a picture wich is more obvious how it rotates... (WINNT.BMP picture in the windows directory :))
This can't be right...
Finally, I figured it out !
I had to inverse either the X or the Y (CW or CCW)
VB Code:
For Y = 0 To FromPic.ScaleHeight - 1 FromPos = Y * BpslFrom For X = 0 To (FromPic.ScaleWidth - 1) * 3 Step 3 'ToPos = (X \ 3) * BpslTo + Y * 3 'ToPos = ((FromPic.ScaleWidth - 1) - (X \ 3)) * BpslTo + Y * 3 ' CW ToPos = (X \ 3) * BpslTo + ((FromPic.ScaleHeight - 1) - Y) * 3 ' CCW DestBitData(ToPos + 0) = BitData(FromPos + X + 0) DestBitData(ToPos + 1) = BitData(FromPos + X + 1) DestBitData(ToPos + 2) = BitData(FromPos + X + 2) Next X Next Y
OK, now i'm gonna start converting it to C++ ....
This is more like it, right ?
DONE !!
For the WINNT.BMP, in VB it took ~ 250 ms, now it takes 20 ms ! :D
Here's the C++ code:
And the Visual Basic code & declarations:Code:_declspec(dllexport) long _stdcall BytesPerScanLine(long width, short bit_count)
{
long ret = width * bit_count;
if((ret % 32) > 0) ret += 32 - (ret % 32);
return ret >> 3;
}
_declspec(dllexport) void _stdcall RotateBMPData_CW(char *from_bmp, long width, long height, char *to_bmp)
{
long x, y, h_add;
long bpsl_from = BytesPerScanLine(width, 24);
long bpsl_to = BytesPerScanLine(height, 24);
char *from_pos, *to_pos;
for(y = 0; y < height; y++)
{
from_pos = from_bmp + y * bpsl_from;
h_add = y * 3;
for(x = 0; x < width; x++)
{
to_pos = to_bmp + ((width - 1) - x) * bpsl_to + h_add;
*(to_pos++) = *(from_pos++);
*(to_pos++) = *(from_pos++);
*(to_pos++) = *(from_pos++);
}
}
}
_declspec(dllexport) void _stdcall RotateBMPData_CCW(char *from_bmp, long width, long height, char *to_bmp)
{
long x, y, h_add;
long bpsl_from = BytesPerScanLine(width, 24);
long bpsl_to = BytesPerScanLine(height, 24);
char *from_pos, *to_pos;
for(y = 0; y < height; y++)
{
from_pos = from_bmp + y * bpsl_from;
h_add = ((height - 1) - y) * 3;
for(x = 0; x < width; x++)
{
to_pos = to_bmp + x * bpsl_to + h_add;
*(to_pos++) = *(from_pos++);
*(to_pos++) = *(from_pos++);
*(to_pos++) = *(from_pos++);
}
}
}
VB Code:
Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Function BytesPerScanLine2 Lib "BitmapStuff.dll" Alias "BytesPerScanLine" (ByVal Width As Long, ByVal BitCount As Integer) As Long Private Declare Function RotateBMPData_CW Lib "BitmapStuff.dll" (ByVal ptrFromData As Long, ByVal Width As Long, ByVal Height As Long, ByVal ptrToData As Long) As Long Private Declare Function RotateBMPData_CCW Lib "BitmapStuff.dll" (ByVal ptrFromData As Long, ByVal Width As Long, ByVal Height As Long, ByVal ptrToData As Long) As Long Private Sub Form_Load() Dim StartTick As Long Picture1.AutoRedraw = True Picture1.Picture = LoadPicture(App.Path & "\Test.jpg") StartTick = GetTickCount RotatePic Picture1, Picture2 Debug.Print "Time: " & GetTickCount - StartTick End Sub Private Sub RotatePic(FromPic As PictureBox, ToPic As PictureBox) Dim BitData() As Byte, DestBitData() As Byte Dim NewSize As Long FromPic.ScaleMode = vbPixels GetBitmapData FromPic.hdc, FromPic.ScaleWidth, FromPic.ScaleHeight, BitData ' reverse width & height NewSize = FromPic.ScaleWidth * BytesPerScanLine2(FromPic.ScaleHeight, 24) ReDim DestBitData(NewSize - 1) RotateBMPData_CW VarPtr(BitData(0)), FromPic.ScaleWidth, FromPic.ScaleHeight, VarPtr(DestBitData(0)) 'RotateBMPData_CCW VarPtr(BitData(0)), FromPic.ScaleWidth, FromPic.ScaleHeight, VarPtr(DestBitData(0)) ToPic.AutoRedraw = True SetBitmapData ToPic.hdc, FromPic.ScaleHeight, FromPic.ScaleWidth, VarPtr(DestBitData(0)) End Sub
I also attached the C++ project with the DLL (In case you don't have the compiler handy)
I made the C++ project in Visual C++ 6.0, this way you can open it even in newer Visual Studio versions
Tell me if you need more help...
Nice bit of code:)
I played around with the VB version and have a few suggestions
1. The line you changed to fix the flipping problem slowed it down on my computer by a factor of 3 so I went back to the original code and flipped the final image with a paintpicture. You have to paint the picture anyway if you want VB to recognize it.
2. It may speed things up if you use a copymemory API call in the loop
3. I also added a line to resize the ToPic
VB Code:
For Y = 0 To FromPic.ScaleHeight - 1 FromPos = Y * BpslFrom For X = 0 To (FromPic.ScaleWidth - 1) * 3 Step 3 [COLOR=Red]ToPos = (X \ 3) * BpslTo + Y * 3[/COLOR] 'ToPos = (X \ 3) * BpslTo + ((FromPic.ScaleHeight - 1) - Y) * 3 'CCW 'ToPos = ((FromPic.ScaleWidth - 1) - (X \ 3)) * BpslTo + Y * 3 'CW [COLOR=Red]CopyMemory DestBitData(ToPos), BitData(FromPos + X), 3[/COLOR] 'DestBitData(ToPos + 0) = BitData(FromPos + X + 0) 'DestBitData(ToPos + 1) = BitData(FromPos + X + 1) 'DestBitData(ToPos + 2) = BitData(FromPos + X + 2) Next X Next Y ToPic.AutoRedraw = True [COLOR=Red]ToPic.Move ToPic.Left, ToPic.Top, FromPic.Height, FromPic.Width[/COLOR] SetBitmapData ToPic.hdc, FromPic.ScaleHeight, FromPic.ScaleWidth, VarPtr(DestBitData(0)) [COLOR=Red] Set ToPic.Picture = ToPic.Image ToPic.PaintPicture ToPic.Picture, 0, ToPic.Height, ToPic.Width, -ToPic.Height[/COLOR]
Not bat moeur, the VB code does it in 80 ms now... (on the same winnt.bmp picture)
Thanks...
[edit]Since there are so many posts in this thread, I won't make a new one..
Anyways, i tested the C++ compared to VB, For a picture of Width=2000, Height=3008, and ran the code 2 times for each...
In VB (with moeur's addition):
Time: 9894
Time: 9804
In C++
Time: 2614
Time: 2524
Good morning. The lack of that "step 3" also resulted in slightly wrong rotated images though I hadn't as yet noticed because I was first trying with grayscale images.Quote:
Originally Posted by CVMichael
CVMichael, that's really great stuff.
I've been testing it on an old computer (one that really sucks) for 2 bitmaps:
1. (651 rows x 621 columns)
With Setpixels: 1950 ms
With your code in VB: 750 ms
With your code in VC++: 208 ms
2. (1189 rows x 1405 columns)
With Setpixels: 9532 ms
With your code in VB: 5699 ms
With your code in VC++: 1001 ms
I was going to rate you up but I couldn't... because I already did :thumb: