# Can't use image() with SVG library

**URL:** <https://discourse.processing.org/t/cant-use-image-with-svg-library/10582>\
**Category:** Processing.py\
**Created:** [April 23, 2019, 9:05pm UTC](https://discourse.processing.org/t/cant-use-image-with-svg-library/10582 "2019-04-23T21:05:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Raums](https://avatars.discourse-cdn.com/v4/letter/r/f0a364/32.png) [@Raums](https://discourse.processing.org/u/Raums)\
**Post date:** [April 23, 2019, 9:05pm UTC](https://discourse.processing.org/t/cant-use-image-with-svg-library/10582/1 "2019-04-23T21:05:41Z")

</div>

Processing throws a NullPointerException when I try to output an image to SVG while using image(). [Looks like this is a known issue from 2017](https://github.com/processing/processing/issues/5267). There’s an answer there but like the poster, I don’t know how to implement it in the context of Processing.

Here’s a python sketch you can use to see the bug for yourself. If you remove beginRecord() and endRecord() it works fine:

```auto
add_library('svg')

def setup():
    size(1000,1000)

def draw():
    beginRecord(SVG, "svgtest.svg")
    
    thisPGraphicsObject = createGraphics(width, height)

    thisPGraphicsObject.beginDraw()
    thisPGraphicsObject.fill(50)
    thisPGraphicsObject.stroke(80)
    thisPGraphicsObject.ellipse(width/2, height/2, 500, 500)
    thisPGraphicsObject.endDraw()
    image(thisPGraphicsObject, 0, 0)
    
    endRecord()

```

NullPointerException  
at org.apache.batik.svggen.ImageHandlerBase64Encoder.encodeImage(Unknown Source)  
at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(Unknown Source)  
at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(Unknown Source)  
at org.apache.batik.svggen.DefaultImageHandler.handleImage(Unknown Source)  
at org.apache.batik.svggen.SimpleImageHandler.handleImage(Unknown Source)  
at org.apache.batik.svggen.SVGGraphics2D.drawImage(Unknown Source)  
at org.apache.batik.ext.awt.g2d.AbstractGraphics2D.drawImage(Unknown Source)  
at processing.awt.PGraphicsJava2D.imageImpl(PGraphicsJava2D.java:1622)  
at processing.core.PGraphics.image(PGraphics.java:3817)  
at processing.core.PApplet.image(PApplet.java:12805)  
at sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)  
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
at java.lang.reflect.Method.invoke(Method.java:498)  
at org.python.core.PyReflectedFunction. **call** (PyReflectedFunction.java:188)  
at org.python.core.PyReflectedFunction. **call** (PyReflectedFunction.java:206)  
at org.python.core.PyObject. **call** (PyObject.java:534)  
at org.python.core.PyObject. **call** (PyObject.java:540)  
at org.python.core.PyMethod. **call** (PyMethod.java:171)  
at org.python.pycode.\_pyx251.draw$2(star\_generator\_2.pyde:129)  
at org.python.pycode.\_pyx251.call\_function(star\_generator\_2.pyde)  
at org.python.core.PyTableCode.call(PyTableCode.java:171)  
at org.python.core.PyBaseCode.call(PyBaseCode.java:125)  
at org.python.core.PyFunction. **call** (PyFunction.java:403)  
at org.python.core.PyFunction. **call** (PyFunction.java:398)  
at jycessing.PAppletJythonDriver.draw(PAppletJythonDriver.java:1370)  
at processing.core.PApplet.handleDraw(PApplet.java:2475)  
at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)  
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)  
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)  
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)  
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)  
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)  
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)  
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)  
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)  
at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)  
at java.util.TimerThread.mainLoop(Timer.java:555)  
at java.util.TimerThread.run(Timer.java:505)

---

<div class="post-metadata">

**Author:** ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)\
**Post date:** [April 24, 2019, 10:45am UTC](https://discourse.processing.org/t/cant-use-image-with-svg-library/10582/2 "2019-04-24T10:45:13Z")

</div>

Okay, this solution is kinda hacky –

SVG is a markup-based language, so perhaps you put in some sort of ‘placeholder’ shape, then open the SVG with any code/text editor and replace the placeholder code with an `<image>` tag?

For example, run this code, then open the SVG and follow the Console output instructions:

```auto
add_library('svg')

size(1000,1000)

beginRecord(SVG, 'svgtest.svg')
fill(50)
stroke(80)
ellipse(width/2, height/2, 500, 500)

fill('#FF0000')
noStroke()
x=10; y=10; w=200; h=200
rect(x, y, w, h)

print('open the svg in a code editor and replace this:')
print('<rect x="%s" y="%s" width="%s" style="fill:red; stroke:none;" height="%s"' % (x,y,w,h) )
print('with is:')
print('<image xlink:href="img.png" x="%s" y="%s" width="%s" height="%s"' % (x,y,w,h) )

endRecord()

```

Of course, you’ll need to replace the `xlink:href="img.png"` attribute with the relevant image path/filename.

You could even take this a step further and include some Python code – after the `endRecord()` – that does the find-replace job automatically. Somebody else may have a better solution, but hopefully, that helps you for now.

---

<div class="post-metadata">

**Author:** ![Raums](https://avatars.discourse-cdn.com/v4/letter/r/f0a364/32.png) [@Raums](https://discourse.processing.org/u/Raums)\
**Post date:** [November 4, 2019, 3:29pm UTC](https://discourse.processing.org/t/cant-use-image-with-svg-library/10582/3 "2019-11-04T15:29:05Z")

</div>

Realizing this might be a different issue than I first thought.

[https://processing.org/reference/libraries/svg/index.html](https://processing.org/reference/libraries/svg/index.html)  
The above says " \* Many methods, particularly pixel-based methods, don’t make sense for SVG renderers. This includes: loadPixels, updatePixels, get, set, mask, filter, copy, blend, save, and image"

Emphasize on “ **and image** ”.

 ![no%20borders](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/0/0d2870205de53ca5848e8ae5b5776bd8ad66065f.png)

Uploaded here is an example of the kind of thing I’m creating. I’m drawing a tesselation to a PGraphics object, drawing a shape to another PGraphic then using it as a mask to cut out a selection of that tesselation in that shape. I then take my ‘cut out’ tesselation and use image to paste it repeatedly, rotated around a circle to create the image here.

My understanding now is that every time I use image I’m effectively converting shape data into pixel data which SVG can’t understand. So, how do I create the same effect while still being able to make an SVG of the combined image? An SVG is important because I’m exporting this to a CNC machine to use as toolpaths that will cut material.

---

<div class="post-metadata">

**Author:** ![villares](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/villares/32/3166_2.png) [@villares](https://discourse.processing.org/u/villares)\
**Post date:** [November 4, 2019, 7:45pm UTC](https://discourse.processing.org/t/cant-use-image-with-svg-library/10582/4 "2019-11-04T19:45:13Z")

</div>

Nice work @Raums!

I’m afraid that pure Processing can’t mask/cut vector data (please someone correct me if I’m wrong). You might have to use a library like Geomerative.

Here a silly example I was playing with:

```python
add_library('geomerative')

def setup():
    size(400, 400)
    RG.init(this)

def draw():
    background(100)
    translate(width / 2, height / 2)

    r0 = rg_rect(mouseX, mouseY, 100, 100, QUARTER_PI)
    r1 = rg_rect(mouseX, -mouseY, 100, 100, 0)
    r2 = rg_rect(-mouseX, -mouseY, 100, 100, QUARTER_PI / 2)
    r3 = rg_rect(-mouseX, mouseY, 100, 100)
    noFill()
    RG.shape(r0)
    RG.shape(r1)
    RG.shape(r2)
    RG.shape(r3)

    result = RG.intersection(r0, r1)
    result = RG.intersection(result, r2)
    result = RG.intersection(result, r3)
    fill(255)
    RG.shape(result)

def rg_rect(x, y, w, h, rot=0):
    r = RShape.createRectangle(0, 0, w, h)
    r.translate(x - w / 2, y - h / 2)
    r.rotate(rot, RPoint(x, y))
    return r

```
