i'm trying to save multiple .bmp files with the D3DXSaveSurfaceToFile method but unable to solve it, i've tried making random strings/wstrings & convert them to LPCWSTR/LPCSTR, using D3DXSaveSurfaceToFileW / D3DXSaveSurfaceToFileA, but all i get is gibberish.
Any ideas of how to do it?
(My project is in C++, Visual Studio, DirectX June 2010)
My solution, if anyone wants it (used char instead):
static int fileIndex = 0;
char fileName[20] = "capture";
sprintf_s(fileName, sizeof(fileName), "%s%d.jpg", fileName, fileIndex);
//sprintf(fileName, "%s%d.jpg", fileName, fileIndex);
size_t size = strlen(fileName) + 1;
wchar_t* wFileName = new wchar_t[size];
size_t outSize;
mbstowcs_s(&outSize, wFileName, size, fileName, size - 1);
//mbstowcs( wFileName, fileName, size - 1);
LPWSTR ptr = wFileName;
D3DXSaveSurfaceToFile(ptr, D3DXIFF_JPG, p, nullptr, nullptr);
fileIndex++;
Related
So I created gif file from 5 png files with using MagickCoalesceImages call and store it on disk.
How I can read these files back from gif file ?
MagickReadImage does not help
Hard to help without seeing the code, but I can assume you created 5 images with something like...
MagickWand
* gif2png;
gif2png = NewMagickWand();
MagickReadImage(gif2png, "input.gif");
MagickWriteImages(gif2png, "output_%02d.png", MagickFalse);
gif2png = DestroyMagickWand(gif2png);
How I can read these files back from gif file?
You would use MagickReadImage to decode the image from the file, and MagickAddImage to append the decoded image onto a image-stack.
MagickWand
* png2gif,
* temp;
// Create a blank image-stack.
png2gif = NewMagickWand();
char filename[PATH_MAX]; // PATH_MAX provided by limits.h
// Iterate over images to append.
for (int i = 0; i < 5; ++i) {
sprintf(filename, "output_%02d.png", i);
// Read image from disk.
temp = NewMagickWand();
MagickReadImage(temp, filename);
// Add "frame" to stack.
MagickAddImage(png2gif, temp);
temp = DestroyMagickWand(temp);
}
MagickWriteImages(png2gif, "output.gif", MagickTrue);
png2gif = DestroyMagickWand(png2gif);
Warning: The above example omits basic error handling, and assumes the filename names are a sequential series.
Update
From the comments, if you wish to extract a single frame as a PNG file, there are a few ways.
Fastest way is to use MagickWriteImages
MagickWriteImages(img, "output_%02d.png", MagickFalse);
Or use the image stack iterators.
for (MagickSetFirstIterator(img); MagickHasNextImage(img); MagickNextImage(img)) {
MagickWriteImage(img, "output_%02d.png");
}
Or, if the PNG filenames are defined, and you need to map them.
const char * filenames[5] = {
"first.png",
"second.png",
"third.png",
"forth.png",
"fifth.png"
};
for (int i = 0; i < 5; ++i) {
MagickSetIteratorIndex(img, i);
MagickWriteImage(img, filenames[i]);
}
Without seeing the code, we can't offer much help, and can only guess what an acceptable solution would be.
Situation: I am trying to get point cloud with pcl::AdaptiveCostSOStereoMatching, which uses two rectified images (pics are ok).
I used these tutorials to learn how to do this:
First tutorial
Second tutorial
Error: programm crashes in runtime when calling "compute" method of AdaptiveCostSOStereoMatching
Question: how to correctly pass images to "compute" method?
I tried:
1) Images converted by png2pcd
(command line: "png2pcd.exe in.png out.pcd")
2) Images converted with function below from cv::Mat
But no luck.
Function which converts cv::Mat to pcl::PointCloud
void MatToPointCloud(Mat& mat, pcl::PointCloud<RGB>::Ptr cloud)
{
int width = mat.cols;
int height = mat.rows;
pcl::RGB val;
val.r = 0; val.g = 0; val.b = 0;
for (int i = 0; i < mat.rows; i++)
for (int j = 0; j < mat.cols; j++)
{
auto point = mat.at<Vec3b>(i, j);
//std::cout << j << " " << i << "\n";
val.b = point[0];
val.g = point[1];
val.r = point[2];
cloud->at(j, i) = val;
}
}
pcl::AdaptiveCostSOStereoMatching (compute)
// Input
Mat leftMat, rightMat;
leftMat = imread("left.png");
rightMat = imread("right.png");
int width = leftMat.cols;
int height = rightMat.rows;
pcl::RGB val;
val.r = 0; val.g = 0; val.b = 0;
pcl::PointCloud<pcl::RGB>::Ptr left_cloud(new pcl::PointCloud<pcl::RGB>(width, height, val));
pcl::PointCloud<pcl::RGB>::Ptr right_cloud(new pcl::PointCloud<pcl::RGB>(width, height, val));
MatToPointCloud(leftMat, left_cloud);
MatToPointCloud(rightMat, right_cloud);
// Calculation
pcl::AdaptiveCostSOStereoMatching stereo;
stereo.setMaxDisparity(60);
//stereo.setXOffest(0); Почему-то не распознается
stereo.setRadius(5);
stereo.setSmoothWeak(20);
stereo.setSmoothStrong(100);
stereo.setGammaC(25);
stereo.setGammaS(10);
stereo.setRatioFilter(20);
stereo.setPeakFilter(0);
stereo.setLeftRightCheck(true);
stereo.setLeftRightCheckThreshold(1);
stereo.setPreProcessing(true);
stereo.compute(*left_cloud, *right_cloud); // <-- CRASHING THERE
stereo.medianFilter(4);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr out_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
stereo.getPointCloud(318.11220, 224.334900, 368.534700, 0.8387445, out_cloud, left_cloud);
Error information:
Output log: HEAP[App.exe]:
Heap block at 0000006B0F828460 modified at 0000006B0F8284A8 past requested size of 38
App.exe has triggered a breakpoint.
left_cloud (a right cloud looks like left_cloud)
Mini question: if AdaptiveCostSOStereoMatching really allows build point cloud from 2 images, how ACSSM doing this without insintric and excentic parameters?
Problem: I downloaded and installed old version of PCL without stereo.
After that, I downloaded stereo from other PCL pack and add this library to my PCL pack. And it worked incorrectly.
Solution: I compilled PCL 1.8 and my programm is ok now.
OS: Windows
IDE: MSVS 12 2013 x64
If you will try to compile PCL, these links can help you:
Official-tutorial-1
Official-tutorial-2
Good help with FLANN and VTK
Example to verify installation
I tried the code in this link Is CUDA pinned memory zero-copy?
The one who asked claims the program worked fine for him
But does not work the same way on mine
the values does not change if I manipulate them in the kernel.
Basically my problem is, my GPU memory is not enough but I want to do calculations which require more memory. I my program to use RAM memory, or host memory and be able to use CUDA for calculations. The program in the link seemed to solve my problem but the code does not give output as shown by the guy.
Any help or any working example on Zero copy memory would be useful.
Thank you
__global__ void testPinnedMemory(double * mem)
{
double currentValue = mem[threadIdx.x];
printf("Thread id: %d, memory content: %f\n", threadIdx.x, currentValue);
mem[threadIdx.x] = currentValue+10;
}
void test()
{
const size_t THREADS = 8;
double * pinnedHostPtr;
cudaHostAlloc((void **)&pinnedHostPtr, THREADS, cudaHostAllocDefault);
//set memory values
for (size_t i = 0; i < THREADS; ++i)
pinnedHostPtr[i] = i;
//call kernel
dim3 threadsPerBlock(THREADS);
dim3 numBlocks(1);
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(pinnedHostPtr);
//read output
printf("Data after kernel execution: ");
for (int i = 0; i < THREADS; ++i)
printf("%f ", pinnedHostPtr[i]);
printf("\n");
}
First of all, to allocate ZeroCopy memory, you have to specify cudaHostAllocMapped flag as an argument to cudaHostAlloc.
cudaHostAlloc((void **)&pinnedHostPtr, THREADS * sizeof(double), cudaHostAllocMapped);
Still the pinnedHostPointer will be used to access the mapped memory from the host side only. To access the same memory from device, you have to get the device side pointer to the memory like this:
double* dPtr;
cudaHostGetDevicePointer(&dPtr, pinnedHostPtr, 0);
Pass this pointer as kernel argument.
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(dPtr);
Also, you have to synchronize the kernel execution with the host to read the updated values. Just add cudaDeviceSynchronize after the kernel call.
The code in the linked question is working, because the person who asked the question is running the code on a 64 bit OS with a GPU of Compute Capability 2.0 and TCC enabled. This configuration automatically enables the Unified Virtual Addressing feature of the GPU in which the device sees host + device memory as a single large memory instead of separate ones and host pointers allocated using cudaHostAlloc can be passed directly to the kernel.
In your case, the final code will look like this:
#include <cstdio>
__global__ void testPinnedMemory(double * mem)
{
double currentValue = mem[threadIdx.x];
printf("Thread id: %d, memory content: %f\n", threadIdx.x, currentValue);
mem[threadIdx.x] = currentValue+10;
}
int main()
{
const size_t THREADS = 8;
double * pinnedHostPtr;
cudaHostAlloc((void **)&pinnedHostPtr, THREADS * sizeof(double), cudaHostAllocMapped);
//set memory values
for (size_t i = 0; i < THREADS; ++i)
pinnedHostPtr[i] = i;
double* dPtr;
cudaHostGetDevicePointer(&dPtr, pinnedHostPtr, 0);
//call kernel
dim3 threadsPerBlock(THREADS);
dim3 numBlocks(1);
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(dPtr);
cudaDeviceSynchronize();
//read output
printf("Data after kernel execution: ");
for (int i = 0; i < THREADS; ++i)
printf("%f ", pinnedHostPtr[i]);
printf("\n");
return 0;
}
I am looking for WIN32 program to copy part of the large 1920x1080px 4:2:0 .YUV file (cca. 43GB) into smaller .YUV files. All of the programs I have used, i.e. YUV players, can only copy/save 1 frame at the time. What is the easiest/appropriate method to cut YUV raw data to smaller YUV videos(images)? SOmething similar to ffmpeg command:
ffmpeg -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]
Here is the Minimum Working Example of the code, written in C++, if anyone will search for a simple solution:
// include libraries
#include <fstream>
using namespace std;
#define P420 1.5
const int IMAGE_SIZE = 1920*1080; // ful HD image size in pixels
const double IMAGE_CONVERTION = P420;
int n_frames = 300; // set number of frames to copy
int skip_frames = 500; // set number of frames to skip from the begining of the input file
char in_string[] = "F:\\BigBucksBunny\\yuv\\BigBuckBunny_1920_1080_24fps.yuv";
char out_string[] = "out.yuv";
//////////////////////
// main
//////////////////////
int main(int argc, char** argv)
{
double image_size = IMAGE_SIZE * IMAGE_CONVERTION;
long file_size = 0;
// IO files
ofstream out_file(out_string, ios::out | ios::binary);
ifstream in_file(in_string, ios::in | ios::binary);
// error cheking, like check n_frames+skip_frames overflow
//
// TODO
// image buffer
char* image = new char[(int)image_size];
// skip frames
in_file.seekg(skip_frames*image_size);
// read/write image buffer one by one
for(int i = 0; i < n_frames; i++)
{
in_file.read(image, image_size);
out_file.write(image, image_size);
}
// close the files
out_file.close();
in_file.close();
printf("Copy finished ...");
return 0;
}
If you have python available, you can use this approach to store each frame as a separate file:
src_yuv = open(self.filename, 'rb')
for i in xrange(NUMBER_OF_FRAMES):
data = src_yuv.read(NUMBER_OF_BYTES)
fname = "frame" + "%d" % i + ".yuv"
dst_yuv = open(fname, 'wb')
dst_yuv.write(data)
sys.stdout.write('.')
sys.stdout.flush()
dst_yuv.close()
src_yuv.close()
just change the capitalized variable into valid numbers, e.g
NUMBER_OF_BYTES for one frame 1080p should be 1920*1080*3/2=3110400
Or if you install cygwin you can use the dd tool, e.g. to get the first frame of a 1080p clip do:
dd bs=3110400 count=1 if=sample.yuv of=frame1.yuv
Method1:
If you are using gstreamer and you just want first X amount of yuv frames from large yuv files then you can use below method
gst-launch-1.0 filesrc num-buffers=X location="Your_large.yuv" ! videoparse width=x height=y format="xy" ! filesink location="FirstXframes.yuv"
Method2:
Calculate size of 1 frames and then use split utility to divide large files in small files.
Use
split -b size_in_bytes Large_file prefix
I am taking a computer graphics class, and I need to work with textures, but I can't use any library to do it. I am stuck on loading the rgb values of the images I need to use (the images can be in any format, jpg, raw, png, etc..) so my question is, which is the easiest way to get the rgb values of an image (of any format) without using any libraries to get this values?? Here is what I found already on the site:
unsigned char *data;
File *file;
file = fopen("image.png", "r");//
data = (unsigned char *)malloc(TH*TV*3); //TH and TV are both 50
fread(data, TH*TV*3, 1, file);
fclose(file);
int i;
for(i=0;i<TH*TV*3;i++){
//suposing I have a struct RGB for the rgb values
RGB.r = data[?];// how do I get the r value
RGB.g = data[?];// how do I get the g value
RGB.b = data[?];// how do I get the b value
}
Thanks
Rather than iterating through every byte that you read in, you want to iterate every pixel which consists of 3 bytes. So replace i++ with i+=3.
for(i=0;i<TH*TV*3;i+=3){
RGB.r = data[i];
RGB.g = data[i+1];
RGB.b = data[i+2];
}
Try to use some framework like OpenCV there are several options to get the colors or to manipulate an image.
Here I found this example code:
cv::Mat img = cv::imread("lenna.png");
for(int i=0; i<img.rows; i++) {
for(int j=0; j<img.cols; j++) {
// You can now access the pixel value with cv::Vec3b
std::cout << img.at<cv::Vec3b>(i,j)[0] << " ";
str::cout << img.at<cv::Vec3b>(i,j)[1] << " ";
str::cout << img.at<cv::Vec3b>(i,j)[2] << std::endl;
}
}
But please note that the code above is not very performance, but the code above should give you an idea how to read the pixels.