Erase parts of image to make pixels transparent - c++

I'm working in openFrameworks, a set of C++ libraries.
What I'm trying to do is simply 'erase' certain pixels of an ofImage (a class that loads/displays an image, and has access to it's pixel array) when a shape (an eraser) passes over the appropriate pixels of the image. Pretty simple stuff - I think - but I'm having a mental block!
ofImage has two methods - getPixels() and getPixelsRef() that seem to approach what I am trying to do, but the methodology I am using is not quite giving me the results I want.
Here is an example of an attempt to update the pixels of a foreground image from the pixels of a background image:
ofPixelsRef fore = foreground.getPixelsRef();
ofPixelsRef back = background.getPixelsRef();
for(int x = 0; x < foreground.getWidth()/2; x++) {
for (int y = 0; y < foreground.getHeight(); y++) {
ofColor c = back.getColor(x, y);
fore.setColor(x, y, c);
}
}
foreground.setFromPixels(fore);
and here is an attempt to statically colour the foreground with a predetermined colour (which I think is what I want to do, with a transparent white ?!?):
ofPixelsRef fore = foreground.getPixelsRef();
ofColor c(0, 127);
for(int x = 0; x < foreground.getWidth(); x++) {
for (int y = 0; y < foreground.getHeight(); y++) {
fore.setColor(x, y, c);
}
}
foreground.setFromPixels(fore);
Neither are quite where I want to get to, but I think they're a stab in the right direction.
If anyone has any ideas on where to proceed, I'm all ears.
I'd consider moving to the ofFbo class, or even GLSL if there's a clean lead/example.
Feel free to post vanilla C++ as well, and I'll see what I can do about porting it to oF.
Thanks,
~ Jesse

FYI, I've found a solution detailed at this page: http://forum.openframeworks.cc/index.php/topic,12899.0.html

Related

Plot a function using SFML

I'm new to SFML. I searched Google to find a way to plot multiple points in SFML from an equation. For example, I want to plot 200 points (x,y) such that y = 2x, in the range (-10 < x < 10).
I couldn't seem to find the right functions to plot points in SFML, because most other functions are just drawing circle and other geometric shapes. If anyone know any functions for graphing in SFML, please tell me (Something like this: https://www.youtube.com/watch?v=jMrnSa6CHfE&t=42s, not the animation, just the plotting part).
Thanks a lot!
As Galik suggested, drawing pixels onto an image is a good solution.
You could try something along the lines of this:
sf::Vector2u size;
sf::Image graph;
graph.create(size.x, size.y, sf::Color(255, 255, 255));
// y = 2x
for (unsigned int x = 0; x < size.x; x++)
{
unsigned int y = 2u * x;
if (y < size.y)
{
graph.setPixel(x, y, sf::Color(0, 0, 0));
}
}

Rendering Tilemap on the screen correctly

I'm having a strange problem rendering my level based on tilemap correctly.
On the y axis all the tiles are normal and aligned, instead on the x axis they seem to be divided by a space i can't figure out why...
I created a matrix with enum values(from 0 to 2) and i cycled my matrix in a for
loop to render the tile with the current number:
ex. GROUND = 0; etc...
Here is a photo of what it looks like
http://it.tinypic.com/r/ali261/8
Here is the sprite for the tile
http://it.tinypic.com/r/21kggw5/8
i will add the code down here.
for(int y = 0; y < 15; y++)
{
for(int x = 0; x < 20; x++)
{
if(map[y][x] == GROUND)
render(tileTex,x*64 - camera.x,y*64 - camera.y,&gTileSprite[0],0,NULL,SDL_FLIP_NONE);
else if(map[y][x] == UGROUND)
render(tileTex,x*64 - camera.x,y*64 - camera.y,&gTileSprite[1],0,NULL,SDL_FLIP_NONE);
else if(map[y][x] == SKY)
render(tileTex,x*64 - camera.x,y*64 - camera.y,&gTileSprite[2],0,NULL,SDL_FLIP_NONE);
tBox[y][x].x = x*64;
tBox[y][x].y = y*64;
tBox[y][x].w = TILE_WIDTH;
tBox[y][x].h = TILE_HEIGHT;
}
}
Further to the comments above, one must be careful to avoid any blurring along the edges of tiles, since their repetition will make any defects more obvious than if they were viewed in isolation.
Blurring may be introduced in the process of drawing portions of the tilemap to the final/intermediate target, or as seems (and has been confirmed) in this case, the source material may have blurred edges.
Particularly when working with images of such 'low` pixel dimensions, one must be vigilant and ensure that any/all resizing operations are performed in an image-editor without re-sampling.
While bilinear/cubic re-sampling may be desired when blitting the assembled image to the screen, it is never desirable for such re-sampling to happen to the source material.

Flip picture horizontal c++ without 2d array

I would like to know if there is anyway to horizontally flip an image without the use of a 2d array. Something similar to this:
for (int x = 0; x < width/2; x++) {
for (int y = 0; y < height; y++) {
int temp = pixelData[x][y];
pixelData[x][y]=pixelData[width-x][y]
pixelData[width-x][y]=temp;
}
}
You can use a single pointer into the image.
You will need to know the distance (amount to increment the pointer) between the end of one raster line (scanline) to the next. So after you increment past the end of a raster line, add the distance to the pointer, so you end up at the left most column on the next raster line.
With modern systems, that have smart GPUs, you may have better efficiency by copying an image to a 2d-array, transforming it, then putting it back. Smarter GPUs may have a mirroring function along with bit-blitting.

Glitchy grid in QGraphicsView::drawBackground

I'm trying to properly display a grid pattern on QGraphicsView::drawBackground. Everything seems to work fine until I try to move an item added to a scene.
I add the line in MainWindow like this:
QPen _Pen;
_Pen.setColor(Qt::red);
_Pen.setWidth(3);
QGraphicsLineItem* _Line=new QGraphicsLineItem(0,0,100,100);
_Line->setPen(_Pen);
_Line->setVisible(true);
_Line->setFlags(QGraphicsLineItem::ItemIsSelectable | QGraphicsLineItem::ItemIsMovable);
m_scene->addItem(_Line);
Methods of GraphicsView:
GraphicsView::GraphicsView() : cellSize(20)
{
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
}
void GraphicsView::drawBackground(QPainter *p, const QRectF &crect)
{
p->save();
p->setPen(QPen(Qt::black,1));
for (int x = crect.topLeft().x(); x < crect.bottomRight().x(); x += cellSize)
for (int y = crect.topLeft().y(); y < crect.bottomRight().y(); y += cellSize)
p->drawPoint(x, y);
p->restore();
}
The problem can be seen here:
When I move the item, it leaves a trail of grid dots behind it, which are not aligned to the original grid.
I don't understand where this error comes from. Have I done something wrong?
I can think of 2 possible issues:
Change the view update mode. The options are described here.
setViewportUpdateMode(SmartViewportUpdate); or setViewportUpdateMode(FullViewportUpdate);
The smear may be caused by the item bounding rectangle of the item being half a pixel too small.
(I realize this question is old, but maybe it will help someone else)
The region you're given in drawBackground is not always the full view. When something on the scene changes, you're given only the relevant region to redraw. And you're starting in the top left corner of different "moving" regions.
One way to fix this would be to make the initial x and y multiples of cellSize:
for (int x = (int)crect.left()/cellSize*cellSize; x < crect.right(); x += cellSize)
for (int y = (int)crect.top()/cellSize*cellSize; y < crect.bottom(); y += cellSize)

Calculate y derivative of image

I want to implement the y derivative of an image.
Given is the following openCV function, who uses a Sobel Operator:
Sobel(gray_input_picture, y_derivative_picture, CV_32FC1 , 0, 1, 3, BORDER_DEFAULT);
There is an example how it looks like:
Now i need to implement it by myself without using this sobel function.
I found some help here: Gradient direction computation
What i now implemented was:
for(int x=0; x<gray_input_picture.rows; x++)
{
for(int y=0; y<gray_input_picture.cols; y++)
{
if(x == gray_input_picture.rows-1 || x == 0)
{
y_derivative.at<Vec3b>(x,y) = gray_input_picture.at<Vec3b>(x,y);
}
else
{
Vec3b color;
color[0] = gray_input_picture.at<Vec3b>(x+1,y)[0] - gray_input_picture.at<Vec3b>(x-1,y)[0];
color[1] = gray_input_picture.at<Vec3b>(x+1,y)[1] - gray_input_picture.at<Vec3b>(x-1,y)[1];
color[2] = gray_input_picture.at<Vec3b>(x+1,y)[2] - gray_input_picture.at<Vec3b>(x-1,y)[2];
y_derivative_picture.at<Vec3b>(x,y) = color;
}
}
}
bitwise_not ( y_derivative_picture, y_derivative_picture2 );
The x and y switch comes from openCV. That's why it's a little bit different. What i don't understand is, that i get a picture which i need to convert (black to white, white to black).
The Result is a little bit different too. It contains blue areas:
Anyone know how i can implement the y derivative better (that it looks similar to the Sobel function)?
Or does anyone know the problem in my implementation?
Thanks!
I think you would probably need to check out what Sobel operator does here:
http://en.wikipedia.org/wiki/Sobel_operator