I have a code on C++, that creates file and writes data to it. Is it possible to use Python's functions to use Python's functionality in my C++ code? For example, I'd like to do this:
# Content of function.py
from PIL import Image
imgObject = Image.open('myfile.jpg') # Create Image object
pixArray = imgObject.load() # Create array of pixels
pixColor = pixArray[25, 25] # Get color of pixel (25,25)
I want to write pixColor to text file using C++ possibilities:
#include <fstream>
#include <iostream>
int main()
{
ofstream fout('color.txt', ios_base::out | ios_base::binary);
fout << pixColor;
}
That's only example. My application will really detect color of each pixel and will output it in 'color.txr' file, so I need something faster than Python. Is there a possibility to do it? Thanks a lot!
You may have a look to boost::python library which is really great for interfacing python and C++.
Related
How do i make a dummy file?
I'm using Visual C++ for a form and I need it to make a dummy file.
I know how to use things like fstream to write to files but how can I do it so that I know the exact size of the resulting file?
I already tried fstuil but that's a CMD command (yes i know you can use system()) whereas i want pure c++.
Try this (creates a 1MB file):
#include <fstream>
int main()
{
std::ofstream ofs("foo.bar", std::ios::binary | std::ios::out);
ofs.seekp((1024*1024) - 1);
ofs.write("", 1);
}
I'm trying to pass the content of a binary file from c++ to node using the node-gyp library. I have a process that creates a binary file using the .fit format and I need to pass the content of the file to js to process it. So, my first aproach was to extract the content of the file in a string and try to pass it to node like this.
char c;
std::string content="";
while (file.get(c)){
content+=c;
}
I'm using the following code to pass it to Node
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), (void*)content.data(), content.size());
args.GetReturnValue().Set(ab);
In node a get an arrayBuffer but when I print the content to a file it is different to the one that show a c++ cout.
How can I pass the binary data succesfully?
Thanks.
Probably the best approach is to write your data to a binary disk file. Write to disk in C++; read from disk in NodeJS.
Very importantly, make sure you specify BINARY MODE.
For example:
myFile.open ("data2.bin", ios::out | ios::binary);
Do not use "strings" (at least not unless you want to uuencode). Use buffers. Here is a good example:
How to read binary files byte by byte in Node.js
var fs = require('fs');
fs.open('file.txt', 'r', function(status, fd) {
if (status) {
console.log(status.message);
return;
}
var buffer = new Buffer(100);
fs.read(fd, buffer, 0, 100, 0, function(err, num) {
...
});
});
You might also find these links helpful:
https://nodejs.org/api/buffer.html
<= Has good examples for specific Node APIs
http://blog.paracode.com/2013/04/24/parsing-binary-data-with-node-dot-js/
<= Good discussion of some of the issues you might face, including "endianness" and "interpreting numbers"
ADDENDUM:
The OP clarified that he's considering using C++ as a NodeJS Add-On (not a standalone C++ program.
Consequently, using buffers is definitely an option. Here is a good tutorial:
https://community.risingstack.com/using-buffers-node-js-c-plus-plus/
If you choose to go this route, I would DEFINITELY download the example code and play with it first, before implementing buffers in your own application.
It depends but for example using redis
Values can be strings (including binary data) of every kind, for
instance you can store a jpeg image inside a value. A value can't be
bigger than 512 MB.
If the file is bigger than 512MB, then you can store it in chunks.
But I wouldnt suggest since this is an in-memory data store
Its easy to implement in both c++ and node.js
I am trying to convert a iamge loaded using PIL to a Cimg image object. I understand that Cimg is a c++ library and PIL is a python imaging library. Given an image url, my aim is to calculate the pHash of an image without writing it onto a disk. pHash module works with a Cimg image object and it has been implemented in C++. So I am planning to send the required image data from my python program to the c++ program using python extension binding. In the following code sniplet, I am loading the image from the given url:
//python code sniplet
import PIL.Image as pil
file = StringIO(urlopen(url).read())
img = pil.open(file).convert("RGB")
The Cimg image object that I need to construct looks as follows:
CImg ( const t *const values,
const unsigned int size_x,
const unsigned int size_y = 1,
const unsigned int size_z = 1,
const unsigned int size_c = 1,
const bool is_shared = false
)
I can get the width(size_x) and height(size_y) using img.size and can pass it to c++. I am unsure of how to fill 'values' field of the Cimg object? What kind of data structure to use to pass the image data from the python to c++ code?
Also, is there any other way to convert a PIL image to Cimg?
I assume that your main application is written in Python and you want to call C++ code from Python. You can achieve that by creating a "Python module" that will expose all native C/C++ functionality to Python. You can use a tool like SWIG to make your work easier.
That's the best solution of your problem that came to my mind.
The simplest way to pass an image from Python to a C++ CImg-based program is via a pipe.
So this a C++ CImg-based program that reads an image from stdin and returns a dummy pHash to the Python caller - just so you can see how it works:
#include "CImg.h"
#include <iostream>
using namespace cimg_library;
using namespace std;
int main()
{
// Load image from stdin in PNM (a.k.a. PPM Portable PixMap) format
cimg_library::CImg<unsigned char> image;
image.load_pnm("-");
// Save as PNG (just for debug) rather than generate pHash
image.save_png("result.png");
// Send dummy result back to Python caller
std::cout << "pHash = 42" << std::endl;
}
And here is a Python program that downloads an image from a URL, converts it into a PNM/PPM ("Portable PixMap") and sends it to the C++ program so it can generate and return a pHash:
#!/usr/bin/env python3
import requests
import subprocess
from PIL import Image
from io import BytesIO
# Grab image and open as PIL Image
url = 'https://i.stack.imgur.com/DRQbq.png'
response = requests.get(url)
img = Image.open(BytesIO(response.content)).convert('RGB')
# Generate in-memory PPM image which CImg can read without any libraries
with BytesIO() as buffer:
img.save(buffer,format="PPM")
data = buffer.getvalue()
# Start CImg passing our PPM image via pipe (not disk)
with subprocess.Popen(["./main"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:
(stdout, stderr) = proc.communicate(input=data)
print(f"Returned: {stdout}")
If you run the Python program, you get:
Returned: b'pHash = 42\n'
I have a problem in my project. There is a project folder on my desktop. I want to create a text file and write something include this text file. That is my code:
ofstream example("/Users/sample/Desktop/save.txt");
But I want to it could been run the other mac. I don't know what I should write addres for save.txt.
Can anyone help me?
Create a file and write some text to it is simple, here is a sample code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
std::ofstream o("/Users/sample/Desktop/save.txt");
o << "Hello, World\n" << std::endl;
return 0;
}
I hope that answers your question but I am not sure if i understand your question correctly, If not please add the details correctly of what you are trying to acheive.
[Update]:
Okay I guess the comment clears the problem.
Your real question is, You want to save the file in the desktop of the user who is playing the game. So getting the path of the current user's desktop is the problem.
I am not sure if there is an portable way to get desktop path but it can be done in following ways:
In Windows:
Using the SHGetSpecialFolderPath() function.
Sample code:
char saveLocation[MAX_PATH] = {0};
SHGetSpecialFolderPath(NULL, saveLocation, CSIDL_DESKTOPDIRECTORY, FALSE);
//Now saveLocation contains the path to the desktop
//Append your file name to it
strcat(saveLocation,"\\save.txt");
ofstream o(saveLocation);
In Linux:
By using environment variables $HOME
sample code:
string path(getenv("HOME"));
path += "/Desktop/save.txt";
ofstream o(path);
Rules defining where-you-should-save-file vary from platform to platform. One option would be to have it part of your compile script (that is you #define SAVEGAME_PATH as part of your compilation configuration), and thus your code itself remain more platform-agnostic.
The alternative is to find a save-data-management library that is already designed to be ported across different platforms. Whether it'd be a C or C++ or whatever-binary-interoperable library then no longer matters.
Just don't expect that to be part of C++ (the language).
if you want your program to run across platform,you'd better use the
relative path.
eg. "./output.txt",or better “GetSystemDirectory()”to obtain the system
directory to create a file,and then you could write or read the file
with the same path..
I will try to be clear ....
My project idea is as follow :
I took several compression algorithms which I implemented using C++, after that I took a text file and applied to it the compression algorithms which I implemented, then applied several encryption algorithms on the compressed files, now I am left with final step which is converting these encrypted files to any format of image ( am thinking about png since its the clearest one ).
MY QUESTION IS :
How could I transform a binary stream into a png format ?
I know the image will look rubbish.
I want the binary stream to be converted to a an png format so I can view it as an image
I am using C++, hope some one out there can help me
( my previous thread which was closed )
https://stackoverflow.com/questions/5773638/converting-a-text-file-to-any-format-of-images-png-etc-c
thanx in advance
Help19
If you really really must store your data inside a PNG, it's better to use a 3rd party library like OpenCV to do the work for you. OpenCV will let you store your data and save it on the disk as PNG or any other format that it supports.
The code to do this would look something like this:
#include <cv.h>
#include <highgui.h>
IplImage* out_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, bits_pr_pixel);
char* buff = new char[width * height * bpp];
// then copy your data to this buff
out_image->imageData = buff;
if (!cvSaveImage("fake_picture.png", out_image))
{
std::cout << "ERROR: Failed cvSaveImage" << std::endl;
}
cvReleaseImage(&out_image);
The code above it's just to give you an idea on how to do what you need using OpenCV.
I think you're better served with a bi-dimensional bar code instead of converting your blob of data into a png image.
One of the codes that you could use is the QR code.
To do what you have in mind (storing data in an image), you'll need a lossless image format. PNG is a good choice for this. libpng is the official PNG encoding library. It's written in C, so you should be able to easily interface it with your C++ code. The homepage I linked you to contains links to both the source code so you can compile libpng into your project as well as a manual on how to use it. A few quick notes on using libpng:
It uses setjmp and longjmp for error handling. It's a little weird if you haven't worked with C's long jump functionality before, but the manual provides a few good examples.
It uses zlib for compression, so you'll also have to compile that into your project.