I am trying to add a target (bullseye) to an image without the use of importing python functions, it is proving to be rather difficult however I believe I need to define a circle through use of code. It should be done by changing the pixels as opposed to importing functions.
Thanks
Needs to be in the centre of an image
You will need to add more information here - how is your image represnted in Python? Normally for porduction code, dealing with images is done through 3rd party modules, each of which have a way to draw or change different pixels. If you are using none you have to define your image reading and writting code (or a way to display the image on the screen).
Anyway, doing all of that without any "importing" will be quite artificial, though feasible.
Maybe you should use pnm files which have a minimum of encoding required.
That said, you could represent the image in memory as a bytesarray object, and use math.sin and math.cos (you will have to import those, or resort to a "raytracing" approach which can render the circle based on x**2 + y * 2 = r ** 2 ) to draw your circle.
Related
I am using SVGPanZoom to manage the zooming of an SVG image in my hybrid Android (for all intents and purposes the same behavior as in Chrome) app. While zooming works well I have found a strange issue. My original inline SVG element goes like this
<svg id='puzzle' viewBox='0 0 1600 770' preserveAspectRatio='none'
width='100vw' height='85.5vh' fill-rule='evenodd' clip-rule='evenodd'
stroke-linejoin='round' stroke-miterlimit='1.414'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://
www.w3.org/1999/xlink'>
Initially this SVG element is empty and gets populated programmatically from JavaScript at run time after which I initiate SVGPanZoom as follows
var panZoom = svgPanZoom('#puzzle',
{panEnabled:false,controlIconsEnabled:false,
zoomEnabled:true,dblClickZoomEnabled:true,onZoom:postZoom});
panZoom.refreshRate = 10;
panZoom.zoomScaleSensitivity = 0.02;
The problem I have run into is this - I want my SVG image to fill the available area, 100vw x 85.5vhcompletely to do which I instruct it via the preserveAspectRatio="none"attribute above along with the viewBox="0 0 1600 770" attribute. I have found that this works - so long as I don't use SVGPanZoom. As soon as I initiate panZoom thezoomBox`attribute gets stripped out and I end up with an image that does not quite behave in terms of its default stretching/filling behavior.
SVGPanZoom is widely used so I assume that this behavior is down to me not quite setting it up properly. Dipping into the code I have found SVGPanZoom creates a cacheViewBoxand then proceeds to remove the original zoomBox attribute.
Which is fine if after that zooming works and the original behavior of the application does not change which is not what I find. What am I doing wrong here?
I've also run into this issue recently. From my research, this is just how the library works. I chose to live with this limitation for now but I found a couple other libraries that may work the way you intend (I haven't tried them yet):
jquery.panzoom is a jquery library that provides this functionality and also has some nice features. I know many people try to avoid jquery but it's pretty small and may do what you want. It handles SVG but I don't know what it does with the viewBox attribute.
react-svg-pan-zoom is a react component which may be useful if you are working in react.
I've also tried the PanZoom library but this also suffers the same viewBox limitation.
A note for anyone running into this thread. In the end I abandoned SVGPanZoom and decided to eschew the route of using any pan/zoom library at all. At the same time I decided to completely stop using the SVG viewBox and handle all zooming/panning entirely on my own through SVG transforms. The core steps involved
Wrap the entire SVG contents in a group to make it easier to manage the transform. I use the id attribute gOuter for this group
Set an initial scale for the SVG to occupy the desired client rectangle. In my case I had an original viewBox of 0 0 1600 770 intended to occupy 100% of screen width and 85% of screen height. So my scaling was scaleX = 1600/window.innerWidth and scaleY = 770/)0.85*window.innerHeight).
Apply this initial transform to the wrapping outer group, gOuter.setAttribute('transform','0 0 scaleX,scaleY)
Now in order to zoom to a an object whose virtual top left hand coordinates in the original viewBox were Ox,Oy you would use the transform
gOuter.setAttribute('transform',
scale(scaleX,scaleY) translate(-Ox,-Oy) scale(2*scaleX,2*scaleY) translate(Ox,Oy))
to zoom in by a factor of x 2. The important things to understand here
In SVG transformations are applied right to left.
Here we are translating the zoom point to the top l.h.s. scaling and then translating it back to its original location.
The problem is that we also need to allow for the original level of zoom through the initial scaling so we tag that on as one last transform
This leaves you in complete control of the zooming process and as a fringe benefit the operation becomes considerably more smooth than when using a pan/zoom library.
After moving, rescaling or rotating a path in fabricjs, I would like to recalculate the path's array coordinates in order to use them later to draw the exact same path on a plain HTML5 canvas.
I have gotten around rotation by storing the angle and then performing a transformation of the whole html canvas. For translation I tried recalculating the points like so:
point[1] = (point[1] + modifiedObject.left - oldState.left);
point[2] = (point[2] + modifiedObject.top - oldState.top);
but this messes up with rescaling on fabric.
I also tried using the transformation matrix on the points, but this didn't work either and I think it's because I am missing some steps in between.
Any help would be appreciated.
Here's a simple demo of what I'm trying to do in essence: https://jsfiddle.net/1b68eLdr/86688/
I am developing on an application based on VTK and GDCM for viewing medical (DICOM) images.
The application has three windows that respectively show XY, YZ and XZ orientations (axial, coronal and sagittal). This is similar to the 2D views here. I use vtkImageViewer2 for this. The voxel values of the DICOM images are passed on to an instance of vtkImageData. The instance of the vtkImageData is the passed on the to three instances of vtkImageViewer2 (let's use imageViewerXY, imageViewerYZ and imageViewerXZ). The orientation of each instance of vtkImageViewer2 is then set using SetSliceOrientationToXY(), SetSliceOrientationToYZ() and SetSliceOrientationToXZ(). Without the mask, I can see the slices, couple the windows and scroll through the images perfectly fine.
To add the mask so that it is shown in the three views, I use vtkImageActor. For the XY view, which is the default view, this works fine. I update the instance of vtkImageActor, which I call maskActorXY based on the mouse events of XY window as follows:
int extent[6];
imageViewerXY->GetImageActor->GetDisplayExtent(extent);
maskActorXY->SetDisplayExtent(extent);
maskActorXY->Update();
imageViewerXY->GetRenerer->Render();
Now, when I do the same for the other two windows so that I can see the 3D mask in the other two orientations, for example for the YZ orientation,
imageViewerYZ->GetImageActor->GetDisplayExtent(extent);
maskActorYZ->SetDisplayExtent(extent);
maskActorYZ->Update();
imageViewerYZ->GetRenerer->Render();
I get an error message that traces to vtkImageData and accessing pixel values outside of the extent set for the mask actor.
I have a limited familiarity with VTK, but looking at the source code of vtkImageViewer2 (see UpdateDisplayExtent() on line 341), I don't understand why pixel values out side of the specified display extent are requested from my instances of vtkImageActor that represent the mask.
I found a solution. Since I am not familiar with VTK, I may not be able to provide a clear explanation. All that I needed were the following two lines for each mask to force its mappers to face the camera:
maskActorYZ->GetMapper()->SetAtFocalPointOn();
maskActorYZ->GetMapper()->SliceFacesCameraOn();
(see [vtkImageMapper3D][1] class.)
Afternoon All,
I'm trying to draw a dynamic "ruler" which can be zoomed (along with the rest of the page) and is annotated, using Raphael.
I've found Raphael's pathBBox() and isBBoxIntersect very useful for determining if a graduation should be printed at a certain point or if it would be too close to another and should thus be skipped.
Now I need to annotate some of the graduations and want to follow a similar method - annotate the largest graduations, working down to the smallest level of detail but skipping drawing the text if it would intersect with some already drawn.
Unfortunately my look through the Raphael docs have only shown me the Paper.print() and Paper.text() methods, both of which add to the paper. This means I would have to add, then find the bbox and test, then remove if bad - which is potentially rather slow.
Is there a way to find the dimensions of some text I want to print without printing it, such that I can manually create a bbox object and test it against my stored bboxes?
As always, thanks very much in advance! :-)
Cheers,
-Oli
You can use .getBBox() on text:
var text = paper.text(...);
if (text.getBBox().width > max) ...;
I didn't see this documented officially, but it works, and apparently cross-browser.
I'm searching for a library that will allow me to perform graphical manipulations on SVG files. By "manipulations" I mean things like:
Merge two overlapping shapes into a single shape
Find the geometric center of a shape
Draw a copy of a shape that is 25% of the original shape's size
...and other sorts of things that one can do in Illustrator.
I need to build a process that can automate these sorts of tasks and perform them on hundreds of SVG files. I realize that I could write scripts to automate this sort of thing in Illustrator, but I need to run this on a remote machine and can't be reliant on having a running instance of Illustrator.
I don't know of a library which directly fulfils the requirements you've listed, but I think these things would not be difficult to script simply using the SVG DOM.
For the first task, it sounds like the easiest thing would simply be to group the two shapes.
var shape1 = document.getElementById("shape1");
var shape2 = document.getElementById("shape2");
var newG = document.createElementNS(svgNs,"g");
shape1.parentNode.removeChild(shape1);
shape2.parentNode.removeChild(shape2);
newG.appendChild(shape1);
newG.appendChild(shape2);
For the second task, you can just get the bounding box of a shape and find the centre point of that.
var bbox = shape1.getBBox();
var centrePoint = {x:bbox.x + bbox.width/2, y:bbox.y + bbox.height/2};
For the third task, you can copy a shape, and then apply a scale transformation to it.
var shape1Clone = shape1.cloneNode(true);
shape1Clone.setAttributeNS(null,"transform","scale(.75)")
In order to automate this so that you can run it on a remote machine, you can use the Apache Batik library, and do the scripting with Rhino. Take a look at this for an example how to do this:
https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/demo/hierarchical-layout/testBatik.sh
https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/demo/hierarchical-layout/testBatik.js
One of the Qt libraries have similar functionality and you can probably do most of the transformation operations with it:
Qt SVG