Is it possible to make a copy of Gdk.image object using lablgtk2 for Ocaml?
I tried to find 'copy' or 'clone' methods but failed.
Maybe you could use pixbuf? It can be created from any drawable.
Here is my clumsy workaround:
let copy_image image =
let w, h = Image.width image, Image.height image in
let copy = Image.create ~kind: `FASTEST ~visual: (Image.get_visual image)
~width: w
~height: h in
for x = 0 to w-1 do
for y = 0 to h-1 do
Image.put_pixel copy ~x:x ~y:y (Image.get_pixel image ~x:x ~y:y)
done
done;
copy
Related
Take a look at the screenshot below. There are three thin SDL 2.0 surfaces displayed, all more or less rectangular.
Blitting image 1 onto image 2 - get image 3
The first surface (the brownish paper one) is Image 1
The white one below it with the two corners missing is Image 2
I would like to perform a SDL_BlitSurface so that Image 1 is blitted onto Image 2, but with the shape of Image 2 (in other words, the end result should look like brown paper, but have two of its corners missing.
To do this, I try:
SDL_BlitSurface(Image1, NULL, Image2, NULL);
But instead of the desired result, I get the third surface in the picture (Image 3), which is the same as Image 1
UPDATE
So on keltar's advice, I've replaced my blit function call with a call to a bespoke function that I hope is copying the alpha channel for each pixel from Image 1 to Image 2
copy_alpha(Image1, Image2);
void IMAGETOOL::copy_alpha(SDL_Surface * src, SDL_Surface * dst)
{
int w = src->w,
h = src->h;
Uint32 opixel, npixel;
Uint8 r, g, b, a;
if (SDL_MUSTLOCK(src)) SDL_LockSurface(src);
if (SDL_MUSTLOCK(dst)) SDL_LockSurface(dst);
Uint8 srcAlpha = 0;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
{
opixel = get_pixel(src, x, y);
SDL_GetRGBA(opixel, src->format, &r, &g, &b, &a);
srcAlpha = a;
opixel = get_pixel(dst, x, y);
SDL_GetRGBA(opixel, dst->format, &r, &g, &b, &a);
a = srcAlpha;
npixel = SDL_MapRGBA(dst->format, r, g, b, a);
put_pixel(dst, x, y, npixel);
}
if (SDL_MUSTLOCK(src)) SDL_UnlockSurface(src);
if (SDL_MUSTLOCK(dst)) SDL_UnlockSurface(dst);
}
The resulting surface has changed. but not in the way I had hoped.
Copying alpha from image 1 to image 2 - get image 3
Not sure what to make of this - any ideas?
Problem solved. In my last update, I was trying to copy alpha from Image 1 to Image 2 - wrong way round!
But when I use the same function to copy alpha from image 2 to Image 1 (I'm guessing that is what keltar meant for me to do).
copy_alpha(Image2, Image1);
the modified Image 1 gives the desired result.
Copying alpha from image 2 to image 1 - get image 3
Thanks for your help keltar!
Using snap.svg.js. Trying to translate the xPos but nothing happens.
Here is the example jsfiddle.net/hswuhdj4
window.objectPool = {
rectQ1: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue}),
rectQ2: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue}),
rectQ3: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue}),
rectQ4: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue}),
rectQ5: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue}),
rectQ6: paper.rect(0,0,0, svgHeight).attr({fill:lighterBlue})
}
I use an objectpool so i can reuse my objects to keep performance.
window.rectsQ = [
objectPool.rectQ1,
objectPool.rectQ2,
objectPool.rectQ3,
objectPool.rectQ4,
objectPool.rectQ5,
objectPool.rectQ6
];
pushing them in an Array rectsQ for easy future access
var rectAmount = 6;
var rectWidth = 100;
for(i=0;i<rectAmount;i++){
paper.node.appendChild(window.rectsQ[i].node); //immitates toFront() function of Raphael.
window.rectsQ[i].attr({width:rectWidth}); //assigning a width
window.rectsQ[i].transform('T' + (svgWidth-(rectWidth*(i+1))) + ' 0');
}
First, I call the object back to the front, then assign a width, finally translate the x-pos, to the right side of the svg-tag.
It doesn't seem too difficult, but for some reason, no matter what transform i do, the object doesn't move.
//It stays right at these coordinates:
x = 0,
y = 0
//while it should be moved to:
x = svgWidth-rectWidth,
y = 0
I've tried using a Relative Translation ('t') instead of absolute Translation ('T'). No luck though.
Does anyone have an idea to why these snap objects won't move, and how to fix it?
Removing the 2 extra arguments helped in the JSFiddle i made, but weirdly enough not in my project.
This is the JSFiddle: http://jsfiddle.net/hswuhdj4/3
FIXED!!
What caused the problem was the local snap.svg.js file.
Changing the directory with the link raw.githubusercontent.com/adobe-webplatform/Snap.svg/master/dist/snap.svg-min.js fixed the problem for me.
Does anyone know how this occurred?
Transform usually takes 2 arguments. I.e. T x y you're giving it 4 though.
The documentation says it works like paths, and if so T x y 0 0 would be the same as T x y T 0 0 which would move the rect to x y and then move it back again to 0 0.
I'm using OsmDroid on OpenStreetMaps and can make markers and polylines, but I can't find any examples on how I'd make 161m/528ft circles around a marker.
a) How do I make circles?
b) How do I make them 161m/528ft in size?
Thanks to MKer, I got an idea on how to solve the problem and made this piece of code, which works:
oPolygon = new org.osmdroid.bonuspack.overlays.Polygon(this);
final double radius = 161;
ArrayList<GeoPoint> circlePoints = new ArrayList<GeoPoint>();
for (float f = 0; f < 360; f += 1){
circlePoints.add(new GeoPoint(latitude , longitude ).destinationPoint(radius, f));
}
oPolygon.setPoints(circlePoints);
oMap.getOverlays().add(oPolygon);`
I know this can be optimized. I'm drawing 360 points, no matter what the zoom is!
If you want a "graphical" circle, then you can implement easily your own CircleOverlay, using the DirectedLocationOverlay as a very good starting point.
If you want a "geographical" circle (than will appear more or less as an ellipse), then you can use the OSMBonusPack Polygon, that you will define with this array of GeoPoints:
ArrayList<GeoPoint> circlePoints = new ArrayList<GeoPoint>();
iSteps = (radius * 40000)^2;
fStepSize = M_2_PI/iSteps;
for (double f = 0; f < M_2_PI; f += fStepSize){
circlePoints.add(new GeoPoint(centerLat + radius*sin(f), centerLon + radius*cos(f)));
}
(warning: I translated from a Nominatim piece of code in PHP, without testing)
The project in question: https://github.com/matutter/Pixel2 is a personal project to replace some out of date software at work. What it should do is, the user adds an image and it generates a color palette of the image. The color palette should have no duplicate colors. (thats the only important stuff)
My question is: why do larger or hi-res or complex images not work as well? (loss of color data)
Using dropzone.js I have the user put a picture on the page. The picture is a thumbnail. Next I use jquery to find the src out of a <img src="...">. I pass that src to a function that does this
function generate(imgdata) {
var imageObj = new Image();
imageObj.src = imgdata;
convert(imageObj); //the function that traverses the image data pulling out RGB
}
the "convert" function pulls out the data fairly simply by
for(var i=0, n=data.length; i<n; i+=4, pixel++ ) {
r = data[i];
g = data[i+1];
b = data[i+2];
color = r + g + b; // format is a string of **r, g, b**
}
finally, the last part of the main algorithme filters out duplicate colors, I only want just 1 occurrence of each... here's the last part
color = monoFilter(color); // the call
function monoFilter(s) {
var unique = [];
$.each(s, function(i, el){
if($.inArray(el, unique) === -1) unique.push(el);
});
unique.splice(0,1); //remove undefine
unique.unshift("0, 0, 0"); //make sure i have black
unique.push("255, 255, 255"); //and white
return unique;
}
I'm hoping someone can help me identify why there is such a loss of color data in big files.
If anyone is actually interesting enough to look at the github, the relivent files are js/pixel2.js, js/dropzone.js, and ../index.html
This is probably the cause of the problem:
color = r + g + b; // format is a string of **r, g, b**
This simply adds the numbers together and the more pixels you have the higher risk you run to get the same number. For example, these colors generate the same result:
R G B
color = 90 + 0 + 0 = 90;
color = 0 + 90 + 0 = 90;
color = 0 + 0 + 90 = 90;
even though they are completely different colors.
To avoid this you can do it like this if you want a string:
color = [r,g,b].join();
or you can create an integer value of them (which is faster to compare with than a string):
color = (b << 16) + (g << 8) + r; /// LSB byte-order
Even an Euclidean vector would be better:
color = r*r + g*g + b*b;
but with the latter you risk eventually the same scenario as the initial one (but useful for nearest color scenarios).
Anyways, hope this helps.
"The problem was that I wasn't accounting for alpha. So a palette from an image that uses alpha would have accidental duplicate records."
I figured this out after finding this Convert RGBA color to RGB
I've been given an assignment to create a RGB bitmap image, provided that the configuration values are given.
And I,ve been told to use visual c++ along with opencv to create the image.
As I'm new in both visual c++ and OpenCV, how to use those tools to create Bitmap? Is there any tutorial that I can use?
This is a really broad question, because I have no idea where your image data is coming from. Are you reading in other image data and saving it to a bitmap? Are you transforming it somehow? If not, are you just programatically filling in the pixels (i.e. create a bitmap filled with a specific color). I'll assume for a minute that the latter is the case.
// Create an empty 3 channel (RGB) image
IplImage* img = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 3);
// Iterate over all of the rows of the image
for(int y = 0; y < 480; ++y)
{
// Iterate over all of the columns of each row
for(int x = 0; x < 640; ++x)
{
// Set each pixel to solid red
((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 0] = 0; // B
((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 1] = 0; // G
((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 2] = 255; // R
}
}
// Save the image data as a bitmap
cvSaveImage("ImAfraidICantLetYouDoThatDave.bmp", img);
// Clean up our memory
cvReleaseImage(&img);
I based all of this on code available at:
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html
Since you're new to visual studio, a fair warning: getting opencv set up under windows is less than trivial. There are plenty of tutorials out there though, so I'm sure you can figure it out. I hope this is helpful.