|
Oh wait, I just saw that I could use NearestNeighbor for the inpterpolation mode. I believe this will solve my problem.
|
|
|
|
|
|
Hi
I am having 10 bmp files and i want to make 1 gif file out of that using GDI+. Each bmp file should be displayed for particular time period. I searched a lot but unable to find the answer. I want to do it in C++.
|
|
|
|
|
Hi all,
I have some problems with directshow filters. I have a device (webcam) that provide some directshow filters for Capture (Source Filter) and Decoder Filter. So with those filters, I can capture and display the video in my local computer.
But I want to get the data from output pin of the Capture filter and using my own RTP stack(symmetric RTP, non-directshow written as a dll) to send it to a remote computer. And in the remote computer, I want to use my RTP stack to receive the video packets and using Decoder Filter to decode the data? So can I do something like that (mixed directshow filters with non-directshow)?
Thank you very much,
DBQ.
|
|
|
|
|
To attach to the output pin of a filter, you'll need to write a filter[^]
or a DMO[^].
I personally use a custom frame grabber filter . The samples
from the grabber filter can be used any way I want, including packaging
and sending on the network.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I'm rewriting a legacy application in C#/WinForms. The previous application (circa Win16) has a feature where it will plot 500,000+ points of data in under two seconds on my development machine.
I've written a plot control in GDI+ that will plot the same data in about 8 seconds on my development machine. This is with the inner loop as optimized as I can possibly get it.
This increase in plot time is unacceptable. The legacy application was written using GDI which is hardware accelerated and GDI+ is generally not.
The two options to fix this as far as I can tell is to write the plotter in GDI or in DirectX. If I write it in GDI, is there documentation anywhere on using it in a C# control (I'd like to use C# types if possible)? Is DirectX overkill and is it fast enough in a managed environment? Is there a third option I'm not thinking of?
I'd appreciate any feedback you guys have on how best to approach this problem.
Thanks,
Aaron
modified 12-Jul-20 21:01pm.
|
|
|
|
|
Aaron Stubbendieck wrote: Is DirectX overkill and is it fast enough in a managed environment? Is there a third option I'm not thinking of?
Considering they use directx in video games I'm sure it is fast enough. I don't think being managed is the main problem actually because I wrote my own graphics work around in vb.net and it is probably >50 times faster than that (I'm not exagerating assuming you meant 500,000 pixels by "500,000 points") and it could probably be optimized further.
If you want a c# work around I found this article http://www.codeproject.com/KB/GDI-plus/csharpgraphicfilters11.aspx[^].
If you would like a copy of my vb.net work around I'd be glad to give it to you (it would be pretty strait forward to convert to c#). I've been meaning to write an article about it for about a year but never got around to writing it.
Mike
|
|
|
|
|
By 500k points I mean 500k x,y pairs, so probably more than 500k pixels.
I keep meaning to learn DX and I'd appreciate taking a look at what you've got to get me started.
Thank you
modified 12-Jul-20 21:01pm.
|
|
|
|
|
Aaron Stubbendieck wrote: I keep meaning to learn DX and I'd appreciate taking a look at what you've got to get me started.
What I wrote doesn't use directx but it is still lightning fast and could be optimited further. Basically I needed it for some image recognition/ai stuff I wanted to display for debugging purposes. The dotnet functions were way too slow on my old laptop.
I will post the code from my graphics module in the next post. If you would like to see it used in an example project I wrote that uses the module please let me know your email and I will send you a zip of my project.
Here's how it works:
1) ReadStream takes a filestream as an argument and reads the pixel and header data into pixelarray and header. If you are not planning to modify an existing bitmap just make an empty one of the dimensions you need to serve this purpose.
2) GetPixel & SetPixel are pretty strait forward. They read or write data into the pixelarray but the results of this are not immediately displayed (there's a reason for this).
3) WriteStream takes the data in the 2 dimensional array and produces a bitmap memorystream.
4) WriteToPictureBox is like WriteStream but it will display the results in a picturebox you specify.
WriteStream & WriteToPictureBox should not be called until after you write all the data because this is by far the slowest of the functions. So if you are drawing a graph call Setpixel for all of the dots and when you are done call WriteToPictureBox to display it. Don't call it after every SetPixel.
This is probably one of the reasons that my code is so fast. It avoids certain repeated calculation that the dotnet methods probably have to use since some of them refresh after every draw.
Please note the example only works for 24 bit bitmaps you will have to modify the code if you want to use other ones. Also pixelarray data starts at position 1x1, I skipped the 0 indexes of the array because I prefer base 1 arrays and I wrote this code for myself originally.
|
|
|
|
|
Please note the example only works for 24 bit bitmaps you will have to modify the code if you want to use other ones. Also pixelarray data starts at position 1x1, I skipped the 0 indexes of the array because I prefer base 1 arrays and I wrote this code for myself originally.
Public Module GraphicsIO
Private Header() As Byte
Private HeaderLen As Integer
Private PixelArray(,) As PixelStr
Public Width As Integer
Public Height As Integer
'reads the data from a filestream into the header and pixelarray
Public Sub ReadStream(ByVal fstream As IO.FileStream)
Dim bytearray() As Byte, len As Integer, rowoffset As Integer, offset As Integer
Dim n As Integer, x As Integer, y As Integer, padding As Integer
Dim remainder As Integer
len = fstream.Length
ReDim bytearray(len)
fstream.Read(bytearray, 0, len) 'copies file stream into an array
'this extracts header information
HeaderLen = System.BitConverter.ToInt32(bytearray, 10)
Width = System.BitConverter.ToInt32(bytearray, 18)
Height = System.BitConverter.ToInt32(bytearray, 22)
ReDim PixelArray(Width, Height)
'this copies the header information into its own array
ReDim Header(HeaderLen)
For n = 0 To (HeaderLen - 1)
Header(n) = bytearray(n)
Next
'each row in a bitmap file must be a multiple of 4
'If not empty padding bytes are added
'This takes that into account and calculates how many padding bytes were added
remainder = (Width * 3) Mod 4
If remainder > 0 Then
padding = 4 - remainder
Else
padding = 0
End If
'this extracts the data and puts it into a 2d array of structures representing the colors
For y = 1 To Height
rowoffset = ((y - 1) * ((3 * Width) + padding))
offset = rowoffset + HeaderLen
For x = 1 To Width
'bitmaps store colors in reverse order: blue, green, red
PixelArray(x, y).B = bytearray(offset) 'blue
offset += 1
PixelArray(x, y).G = bytearray(offset) 'green
offset += 1
PixelArray(x, y).R = bytearray(offset) 'red
offset += 1
Next
Next
End Sub
'displays the image on the picturebox
Public Sub WriteToPictureBox(ByVal pictbox As PictureBox)
Dim myimage As Image, mstream As New IO.MemoryStream
mstream = GraphicsIO.WriteStream(mstream)
myimage = Image.FromStream(mstream)
pictbox.Image = myimage
Form1.GloImage = myimage
End Sub
'creates a file stream from the pixelarray
Public Function WriteStream(ByVal mstream As IO.MemoryStream)
Dim rowoffset As Integer, offset As Integer, bytearray() As Byte, len As Integer
Dim n As Integer, x As Integer, y As Integer, padding As Integer
Dim remainder As Integer
'Each row in a bitmap file must be a multiple of 4
'If not empty padding bytes are added
'This takes that into account and calculates how many padding bytes to add
remainder = (Width * 3) Mod 4
If remainder > 0 Then
padding = 4 - remainder
Else
padding = 0
End If
len = HeaderLen + (Height * ((Width * 3) + padding))
ReDim bytearray(len)
'copies the header into the byte array
For n = 0 To (HeaderLen - 1)
bytearray(n) = Header(n)
Next
'this extracts the data from a 2d array of structures representing the colors
For y = 1 To Height
rowoffset = ((y - 1) * ((3 * Width) + padding))
offset = rowoffset + HeaderLen
For x = 1 To Width
'bitmaps store colors in reverse order: blue, green, red
bytearray(offset) = PixelArray(x, y).B
offset += 1
bytearray(offset) = PixelArray(x, y).G
offset += 1
bytearray(offset) = PixelArray(x, y).R
offset += 1
Next
Next
'copies the bytearray into the memory stream
mstream.Write(bytearray, 0, len)
Return mstream
End Function
'reads a pixel
Public Sub GetPixel(ByVal x As Integer, ByVal y As Integer, ByRef r As Integer, ByRef g As Integer, ByRef b As Integer)
Dim pixel As PixelStr
pixel = PixelArray(x, y)
r = pixel.R
g = pixel.G
b = pixel.B
End Sub
'reads a pixel
Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As PixelStr
Dim pixel As PixelStr
pixel = PixelArray(x, y)
Return pixel
End Function
'writes a pixel
Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal r As Integer, ByVal g As Integer, ByVal b As Integer)
PixelArray(x, y).R = r
PixelArray(x, y).G = g
PixelArray(x, y).B = b
End Sub
Public Structure PixelStr
Public R As Byte 'red
Public G As Byte 'green
Public B As Byte 'blue
End Structure
End Module
|
|
|
|
|
1. C# does automatic array-bounds checking which slows it down. Try putting your plotting code inside an unsafe { } block, which may speed it up.
2. Your code is executed in a pipeline, where several consecutive instructions may be in various stages of execution at any one point. When you branch (i.e. go back to the top of your inner loop) it messes this up.
Drawing multiple points in your inner loop (called "loop unrolling") allows your program to take advantage of pipelining. E.g. instead of
while ()
{
draw point n
}
Try:
while ()
{
draw point n
draw point n+1
draw point n+2
draw point n+3
}
3. You can write a faster plotting function in C++ using GDI and put it in a DLL. Then you can call this DLL from C#.
|
|
|
|
|
I got a marginal increase in performance with the unsafe block, I'll try unrolling my loop and if that doesn't work we'll get down and dirty with GDI.
Thanks
modified 12-Jul-20 21:01pm.
|
|
|
|
|
Hi,
before you make drastic changes, you might consider showing some of your actual code, so CPians get a chance of offering specific advice about it.
|
|
|
|
|
I know this is late comings but you might want to look at OpenGL via the Tao wrapper. Drawing point is stupid simple and can be optimized multiple ways.
ARon
|
|
|
|
|
Hello all,
I'm very new in DirectX programming (Actually I started 2 hours ago!!! ). I'm reading a great ebook about DirectX in VC++ and I'm trying to convert that codes into C# but I couldn't find the reference of Direct3DCreate9 method. My ebook includes d3d9.h in its code, I found d3d9.dll in system32 folder but I couldn't add that as a reference.
1 - Can I use this method in C#?
If yes,
2 - What is its reference?
Thank you in advance.
When you're alone in the Dark, Fear will protect you...
|
|
|
|
|
In C#, you are using the NET Framework version of DirectX. I don't think you actually reference the DirectX DLLs, you just add the using namespace declarations at the beginning of your source version:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;
And, the path to the DirectX libraries must be known to the compiler. I program in C++, which allows you to use either managed or unmanaged versions of DirectX; the syntax is slightly different for C++ and C#. There are numerous tutorials for beginning DirectX using the NET Framework on the internet. The DirectX 9 SDK has numerous examples and that's probably the best place to start. Also, there are numerous C# DirectX tutorials right here at Codeproject.
A good introductory article on mamaged DirectX is : HERE at MSDN Magazine[^]
|
|
|
|
|
Hi Baltoro, Thanks for reply.
Actually I searched all Microsoft.Direct3D namespace (include all its classes and namespaces) for Direct3DCreate9 but I couldn't find anything! I couldn't find something useful in Google too.
Maybe I should use some other methods in C#. Currently searching for that. If you have any reference or anything, I'll be glad to hear that.
However thanks
When you're alone in the Dark, Fear will protect you...
|
|
|
|
|
|
Thanks a lot, you made my day.
Reading your links is in progress...
Life is 5: 3 me, 1 you.
|
|
|
|
|
I highly recommend avoiding Managed DirectX as its now effectively a legacy API. XNA is the replacement, but if the limitations and general "xboxyness" of it bother you, then I suggest you use SlimDX.
SlimDX has a bunch of examples - and you can also follow the official C++ API to a certain extent to get a rough idea of what is going on. Its a much better managed directx wrapper than the original.
|
|
|
|
|
hi..
I'm using Splitcontainer and drawing a bitmap on the panel2 of the Splitcontainer, now i need to capture the panel2 waveform and save it to bit map.. so pls help me how to capture and save the waveform (panel2 contents).
if possible provide me some reference links..
thanks in advance
vinay
|
|
|
|
|
i wana to load a JPG file and render it on gui,but no any result however...and every time it prints: Render PIC SUC!! and i cannot resolve the problem,my code is:
void CTestLoadJPEGDlg::OnBtnNew()
{
CFileDialog cFileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "File(*.JPEG;*.JPG;*.BMP)|*.JPEG;*.JPG;*.BMP||", NULL);
if (IDOK == cFileDlg.DoModal())
{
CString strPicFilePath;
strPicFilePath = cFileDlg.GetPathName();
TRACE("the file path:%s\n",strPicFilePath);
CFile cFile(strPicFilePath,CFile::modeRead);
int nPicFileBufSize = cFile.GetLength();
HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, nPicFileBufSize);
if(NULL != hGlobal)
{
LPVOID lpData = NULL;
lpData = ::GlobalLock(hGlobal);
if (NULL != lpData)
{
cFile.ReadHuge(lpData, nPicFileBufSize);
GlobalUnlock(hGlobal);
IStream *pIstream = NULL;
CreateStreamOnHGlobal(hGlobal,TRUE,&pIstream);
if (NULL != pIstream)
{
HRESULT hr = ::OleLoadPicture(pIstream, nPicFileBufSize, TRUE, IID_IPicture, (LPVOID*)&m_iPicture);
if (FAILED(hr))
{
TRACE("OleLoadPicture failed!!\n");
goto CLOSEFILE;
}
pIstream->Release();
}
}
else
{
TRACE("lpData=NULL!!!\n");
goto CLOSEFILE;
}
}
else
{
TRACE("hGlobal=NULL!!!\n");
goto CLOSEFILE;
}
if (NULL != m_iPicture)
{
CSize sizeInHimetric;
HRESULT hr = NULL;
hr = m_iPicture->get_Width(&sizeInHimetric.cx);
if (FAILED(hr))
{
TRACE("get_Width failed!!\n");
goto CLOSEFILE;
}
hr = m_iPicture->get_Height(&sizeInHimetric.cy);
if (FAILED(hr))
{
TRACE("get_Height failed!!\n");
goto CLOSEFILE;
}
HDC hDCScreen = ::GetDC(NULL);
int nPixelsPerInchX = ::GetDeviceCaps(hDCScreen, LOGPIXELSX);
int nPixelsPerInchY = ::GetDeviceCaps(hDCScreen, LOGPIXELSY);
::ReleaseDC(NULL, hDCScreen);
CSize sizeInPixel;
sizeInPixel.cx = MulDiv(sizeInHimetric.cx, nPixelsPerInchX, HIMETRIC_PER_INCH);
sizeInPixel.cy = MulDiv(sizeInHimetric.cy, nPixelsPerInchY, HIMETRIC_PER_INCH);
m_szPicPixel = sizeInPixel;
m_szPicHimetric = sizeInHimetric;
DrawPic();
}
CLOSEFILE:
cFile.Close();
}
return;
}
void CTestLoadJPEGDlg::DrawPic()
{
if (NULL == m_iPicture)
{
TRACE("m_iPicture=NULL!!\n");
return;
}
CRect rect;
m_staticPicRect.GetWindowRect(rect);
CPoint ptTopLeft;
ptTopLeft = rect.TopLeft();
float fZoomRate = 1.0;
int xSrcPos = (int)(ptTopLeft.x / fZoomRate);
int ySrcPos = (int)(ptTopLeft.y / fZoomRate);
int cxSrcWidth = (int)(rect.Width() / fZoomRate);
int cySrcHeight = (int)(rect.Height() / fZoomRate);
CDC* dc = GetDC();
int nPixelsPerInchX = ::GetDeviceCaps(*dc, LOGPIXELSX);
int nPixelsPerInchY = ::GetDeviceCaps(*dc, LOGPIXELSY);
int xHimetric = MulDiv(xSrcPos, HIMETRIC_PER_INCH, nPixelsPerInchX);
int yHimetric = MulDiv(ySrcPos, HIMETRIC_PER_INCH, nPixelsPerInchY);
int wHimetric = MulDiv(cxSrcWidth, HIMETRIC_PER_INCH, nPixelsPerInchX);
int hHimetric = MulDiv(cySrcHeight, HIMETRIC_PER_INCH, nPixelsPerInchY);
HRESULT hr = m_iPicture->Render(dc->GetSafeHdc(), rect.left, rect.top, rect.Width(), rect.Height(),
xHimetric, yHimetric, wHimetric, hHimetric, NULL);
if (FAILED(hr))
{
TRACE("Render failed!!\n");
return;
}
TRACE("Render PIC SUC!!\n");
}
thks again!
|
|
|
|
|
It appears that you are trying to use the code from: Load JPEG and Transparant GIF Picture Files From a Resource in 3 Lines Code[^]
What exactly are you trying to do?
It also appears that you are pasting code from various sources, just to get it to work.
You should probably rethink your approach,...if you are merely trying to display a JPG image, there are MUCH simpler ways of doing it. This has the advantage that you will actually clearly understand how the code operates. If you are a novice at this kind of thing, this is important.
Does your application have to be MFC? Which operating system are you compiling for? Are you actually using a resource from your executable?
On the other hand, if you want to use the code as is, I would start off by reading the HRESULT error code returned by IPicture->Render and OleLoadPicture. Look in Winerror.h. HRESULTS[^]. The FAILED or SUCCEEDED Macros don't tell you much.
Maybe this MSDN article will help: Displaying a JPEG in your MFC Application[^].
The Source Code accompanying that article is here: Source Classes[^]
There are plenty of problems with your code, as it is.
|
|
|
|
|
thanku very much. i got it.
|
|
|
|
|
Here's a much simpler start:
#include <atlimage.h>
...
CFileDialog cFileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("File(*.JPEG;*.JPG;*.BMP;*.PNG;*.TIF;*.GIF)|*.JPEG;*.JPG;*.BMP;*.PNG;*.TIF;*.GIF||"), NULL);
if (IDOK == cFileDlg.DoModal())
{
CString strPicFilePath = cFileDlg.GetPathName();
CImage SrcBitmap;
SrcBitmap.Load(strPicFilePath);
CClientDC dc(this);
SrcBitmap.Draw(dc, 0, 0);
SrcBitmap.Destroy();
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|