I'm using the Graphviz API in a project. EVereything is okay except that when I run the executable I get
Error: renderer for png is unavailable
How do I go about solving this?
On CentOS there's a package called "graphviz-gd" which contains some plugin renderers. If you check in "/usr/lib/graphviz/config" what you see is this:
libgvplugin_gd.so.3 gd {
render {
gd 1
gd2 1
gif 1
jpg 1
jpeg 1
png 1
wbmp 1
}
render {
vrml 1
}
textlayout {
textlayout 2
}
loadimage {
gif2gd 1
jpeg2gd 1
png2gd 1
gif2ps 1
jpeg2ps 1
png2ps 1
}
}
If you don't have that particular library, none of those features will work. Not sure about Ubuntu, probably a similar package name.
Related
I have this project in ruby on rails and recently I changed the upload image functionality to Shrine.
I want be able to upload an animated gif and then create an static jpeg (or gif if it's easier) derivative.
I am trying this way
class GifUploader < Shrine
Attacher.derivatives do |original|
magick = ImageProcessing::MiniMagick
{
static: magick.loader(page: 0)
.loader(geometry: "450x250")
.call(original),
}
end
end
With this approach I received this error
MiniMagick::Error: `convert /tmp/shrine20211117-94958-ieep9h.gif[0][450x250] -au
to-orient /tmp/image_processing20211117-94958-q3i2qe.gif` failed with error:
convert-im6.q16: unable to open image `/tmp/shrine20211117-94958-ieep9h.gif[0][450x250]': No such file or directory # error/blob.c/OpenBlob/2924.
convert-im6.q16: no decode delegate for this image format `' # error/constitute.c/ReadImage/575.
convert-im6.q16: no images defined `/tmp/image_processing20211117-94958-q3i2qe.gif' # error/convert.c/ConvertImageCommand/3229.
I also tried a different approach and gave me the same error:
require "image_processing/mini_magick"
class GifUploader < Shrine
Attacher.derivatives do |original|
magick = ImageProcessing::MiniMagick.source(original)
{
static: magick # original is a IO object
.loader(page: 0)
.loader(geometry: "450x250")
.convert!("jpeg")
.call(original),
}
end
end
This is my first project in ruby on rails and I don't know what is happening. I already searched for it, but no results
I am using ruby on rails 6
Okay, I managed to fix this. Basically I inverted the order and get rid of any "!" points. I also deleted the loader(geometry: "450x250")
The code:
require "image_processing/mini_magick"
class GifUploader < Shrine
Attacher.derivatives do |original|
magick = ImageProcessing::MiniMagick.source(original)
{
static: magick.convert("jpeg").loader(page: 0).call
}
end
end
I don't know why this worked, if anyone knows please explain in the comments
The p5 docs state how to load an image from the assets folder.
However I am using 'instance mode' in my Vue 3 setup and any attempt to use loadImage is resulting in the return of an Event object of type"error" and no explanation.
I have tried:
const script = p5 => {
...
this.assets.rocket = p5.loadImage('./assets/rocket.jpg')
this.assets.rocket = p5.loadImage('~assets/rocket.jpg')
this.assets.rocket = p5.loadImage('#/assets/rocket.jpg')
}
and so on.
I know the image exists as <img src="./assets/rocket.jpg"> renders the image correctly.
What have I missed?
(Everything else regarding p5 in instance mode appears to be working fine.)
Try p5.loadImage(require('#/assets/rocket.jpg'))?
Importing image should be a Webpack responsibility, not p5.js
I am using the following Java code to read a Dicom image, trying to convert it later to JPEG file. When the reading happens in the line
tempImage = ImageIO.read(dicomFile);
, the returned image either has an image type of 10 or something else, like 0 or 11. The problem here is that the reading happens sporadically. Sometimes the returned image type is 10, and sometimes it is not.
When the returned image type is 10, the writing of the converted JPEG file succeeds and returns true and I get my JPEG file. However, when the returned image type is not 10, the writing fails and returns false, and doesn't produce any file. This is the statement I am using for writing:
writerReturn = ImageIO.write(image, "jpeg", new File(tempLocation + studyId + File.separator + seriesUID + File.separator + objectId + thumbnail+ ".jpeg"));
I have spent long time trying to figure out why this sporadic behaviour is happening but couldn't reach to anything. Could you please help?
I am guessing the issue is that your input image is 16bits while I am sure your code only accept 8bits input. You cannot write out using the so-called usual JPEG 8bits lossy format unless you transform your 16bits input.
On my box here is what I see:
$ gdcminfo 1.2.840.113619.2.67.2200970061.29232060605151433.387
MediaStorage is 1.2.840.10008.5.1.4.1.1.1.1 [Digital X-Ray Image Storage - For Presentation]
TransferSyntax is 1.2.840.10008.1.2.4.90 [JPEG 2000 Image Compression (Lossless Only)]
NumberOfDimensions: 2
Dimensions: (1887,1859,1)
SamplesPerPixel :1
BitsAllocated :16
BitsStored :14
HighBit :13
PixelRepresentation:0
ScalarType found :UINT16
PhotometricInterpretation: MONOCHROME2
PlanarConfiguration: 0
TransferSyntax: 1.2.840.10008.1.2.4.90
Group 0x6000
Rows 1859
Columns 1887
NumberOfFrames 0
Description
Type G
Origin[2] 1,1
FrameOrigin 0
BitsAllocated 1
BitPosition 0
Origin: (0,0,0)
Spacing: (0.187429,0.187429,1)
DirectionCosines: (1,0,0,0,1,0)
Rescale Intercept/Slope: (0,1)
Orientation Label: AXIAL
So if you want to convince yourself you could extract the encapsulated JPEG 2000 bytestream:
$ gdcmraw 1.2.840.113619.2.67.2200970061.29232060605151433.387 bug.j2k
$ file bug.j2k
bug.j2k: JPEG 2000 codestream
I was able to open the generated bug.j2k using either IrfanView and kdu_show, but as you can see the image is very dark (only the lower bits are read).
From extra information in the comments, we have discovered that the application is running in a Glassfish server, and that there are two ImageIO plugins installed, both capable of reading DICOM images. The problem is not really related to reading, but sometimes writing the decoded image to JPEG fails.
The service providers for mentioned plugins are org.dcm4cheri.imageio.plugins.DcmImageReaderSpi and
org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi, but only the latter (DicomImageReaderSpi) seems to work. This is because it produces an 8 bits per sample BufferedImage, which is what the JPEGImageWriter is able to write (the DcmImageReaderSpi creates a 16 bit per sample image, which can't be written as a JFIF JPEG and thus unsupported by the JPEGImageWriter).
Because of the (by default) unspecified (read: unpredictable) order of ImageIO plugins, the result is that sometimes you get the 8 bps version and sometimes the 16 bit version of the image, and the end result is that sometimes the conversion won't work.
Now, the good news is that we can set an explicit order of ImageIO plugins, or we can unregister plugins at runtime, to get a stable predictable result. What is the better of these options, depends on wether there are other code on your server that depends on the undesired plugin or not. If you don't need it, unregister it.
The code below shows both of the above options:
// Get the global registry
IIORegistry registry = IIORegistry.getDefaultInstance();
// Lookup the known providers
ImageReaderSpi goodProvider = lookupProviderByName(registry, "org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi");
ImageReaderSpi badProvider = lookupProviderByName(registry, "org.dcm4cheri.imageio.plugins.DcmImageReaderSpi");
if (goodProvider != null && badProvider != null) {
// If both are found, EITHER
// order the good provider BEFORE the bad one
registry.setOrdering(ImageReaderSpi.class, goodProvider, badProvider);
// OR
// un-register the bad provider
registry.deregisterServiceProvider(badProvider);
}
// New and improved (shorter) version. :-)
private static <T> T lookupProviderByName(final ServiceRegistry registry, final String providerClassName) {
try {
return (T) registry.getServiceProviderByClass(Class.forName(providerClassName));
}
catch (ClassNotFoundException ignore) {
return null;
}
}
You should also make sure you run this code only once, for a container-based application, a good time is at application context start-up.
With the above solution, ImageIO.read(...) will always use the good plugin, and ImageIO.write(...) will work as expected.
I am trying to compress a png and save it as jpg:
i = Image.read("http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png").first
it's size is 799 kb:
http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png=>e2558b0d34221d3270189320173dabc2.png PNG 640x639 640x639+0+0 DirectClass 8-bit 799kb
I set the format to jpeg and quality to 10 (i.e very poor quality so file size should be greatly reduced):
i.format = 'JPEG'
i.write("itest10.png") { self.quality = 10 }
The size actually increases to 800kb!
=> http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png=>itest40.png PNG 640x639 640x639+0+0 DirectClass 8-bit 800kb
1) Why?
2) How can I compress the photo so the size is < 150kb ?
Thanks!
The use of '.png' extension will change the format back to PNG on the call to write.
There are two possible solutions.
First, I'd recommend using the normal file extension for your format if possible, because a lot of computer systems will rely on that:
i = Image.read( 'demo.png' ).first
i.format = 'JPEG'
i.write( 'demo_compressed.jpg' ) { |image| image.quality = 10 }
If this is not possible, you can set the format inside the block passed to write, and this will apply the format after the extension has been processed:
i = Image.read( 'demo.png' ).first
i.write( 'demo_compressed.png' ) do |image|
image.format = 'JPEG'
image.quality = 10
end
In both the above cases, I get the expected high compression (and low quality) jpeg format image.
This has been updated due to recent RMagick changes (thanks to titan for posting comment). The orginal code snippets were
i.write( 'demo_compressed.jpg' ) { self.quality = 10 }
and
i.write( 'demo_compressed.png' ) do
self.format = 'JPEG'
self.quality = 10
end
These may still work in older RMagick installations.
I tried the other answer and I was still having issues with the transparency. This code here work fine for me:
img_list = Magick::ImageList.new
img_list.read( 'image.png' )
img_list.new_image( img_list.first.columns, img_list.first.rows ) {
self.background_color = "white"
}
imageJPG = img_list.reverse.flatten_images
imageJPG.write( "out.jpg" )
The idea is first create an imageList then load the PNG image into it and after that add a new image to that list and set its bg to be white. Then just reverse the order of the list then flatten the image list into a single image. To add compression just do the self.quality thing from the above answer.
Does there exist a Haskell graphics library or binding to an external library that fulfills the following requirements:
Can be used from ghci, i.e. I don't have to link and restart the program.
Works on MacOS X. (Tricky in conjunction with 1!)
Can do simple vector graphics (lines, polygons, simple fills and strokes).
Can put bitmap images on screen. Example: blit a 17x12 .bmp image.
?
Please include a minimal source code example or a reference to it (just a window on screen, maybe with a green line drawn inside it) so that I can check the points 1. and 2. in particular. Also, if one of these feature requests is more elaborate (for example OpenGL + 4), please include a good reference.
PS: Concerning 1 and 2, I know about the enableGUI trick and I am willing to use it. However, most libraries have the problem that you can't run the main function multiple times and hence don't qualify.
Edit: To avoid wasting your time, here a list of packages that I've tried:
wx - ghci chokes on libstdc++
sdl - redefines main to be a macro. Compile-time only.
GLFW (OpenGL) - Can't run main twice, something about "failing because it can't install mouse event handler".
EDIT: Actually, I'm no longer sure. Several versions later, it seems that GLFW no longer works in GHCi on OS X.
It turns out that GLFW+OpenGL fulfills all four requirements!
You need to invoke ghci with ghci -framework Carbon.
You need the EnableGUI.hs file, which you can get here. Note that you can't load it right into GHCi, you have to comiple it, first.
OpenGL has a 2D projection mode where you can draw lines and polygons.
Bitmaps can be loaded as textures and put on polygons.
Here is a small example that puts a bitmap onto the screen. There are some restrictions on the bitmap: its dimensions must be a power of two (here 256) and it must be a .tga file (here "Bitmap.tga"). But since transparency is supported, this is not much of a problem.
You should be able to call main multiple times without problem. The key point is that you should not call GLFW.terminate.
import Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLFW as GLFW
import Graphics.Rendering.OpenGL (($=))
import Control.Monad
import EnableGUI
main = do
enableGUI
GLFW.initialize
-- open window
GLFW.openWindow (GL.Size 400 400) [GLFW.DisplayAlphaBits 8] GLFW.Window
GLFW.windowTitle $= "Bitmap Test"
-- enable alpha channel
GL.blend $= GL.Enabled
GL.blendFunc $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
-- set the color to clear background
GL.clearColor $= GL.Color4 0.8 0.8 0.8 0
-- set 2D orthogonal view inside windowSizeCallback because
-- any change to the Window size should result in different
-- OpenGL Viewport.
GLFW.windowSizeCallback $= \ size#(GL.Size w h) ->
do
GL.viewport $= (GL.Position 0 0, size)
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.ortho2D 0 (realToFrac w) (realToFrac h) 0
render <- initialize
loop render
GLFW.closeWindow
loop render = do
-- draw the entire screen
render
-- swap buffer
GLFW.swapBuffers
-- check whether ESC is pressed for termination
p <- GLFW.getKey GLFW.ESC
unless (p == GLFW.Press) $ do
-- sleep for 1ms to yield CPU to other applications
GLFW.sleep 0.001
-- only continue when the window is not closed
windowOpenStatus <- GLFW.getParam GLFW.Opened
unless (windowOpenStatus == False) $
loop render
-- rendering
initialize = do
-- load texture from file
GL.texture GL.Texture2D $= Enabled
[textureName] <- GL.genObjectNames 1
GL.textureBinding GL.Texture2D $= Just textureName
GL.textureFilter GL.Texture2D $= ((GL.Nearest, Nothing), GL.Nearest)
GLFW.loadTexture2D "Bitmap.tga" []
return $ do
GL.clear [GL.ColorBuffer]
GL.renderPrimitive GL.Quads $ do
GL.texCoord $ texCoord2 0 0
GL.vertex $ vertex3 (0) 256 0
GL.texCoord $ texCoord2 0 1
GL.vertex $ vertex3 (0) (0) 0
GL.texCoord $ texCoord2 1 1
GL.vertex $ vertex3 256 (0) 0
GL.texCoord $ texCoord2 1 0
GL.vertex $ vertex3 256 256 0
-- type signatures to avoid ambiguity
vertex3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vertex3 GLfloat
vertex3 = GL.Vertex3
texCoord2 :: GLfloat -> GLfloat -> GL.TexCoord2 GLfloat
texCoord2 = GL.TexCoord2
color3 :: GLfloat -> GLfloat -> GLfloat -> GL.Color3 GLfloat
color3 = GL.Color3
Here an example bitmap (which you need to convert to .tga).
The Gtk2Hs library fulfills all the requirements if you use the X11 version of the gtk2 framework.
Concerning the requirements:
Using X11 avoids many problems.
Install gtk2 via MacPorts and use the +x11 option (default). (That said, I've had numerous problems installing gtk2 in the past, but this time it seemed to work.)
I would be surprised if GTK+ can't do that.
Ditto.
Here a minimal example
import Graphics.UI.Gtk
hello :: (ButtonClass o) => o -> IO ()
hello b = set b [buttonLabel := "Hello World"]
main :: IO ()
main = do
initGUI
window <- windowNew
button <- buttonNew
set window [windowDefaultWidth := 200, windowDefaultHeight := 200,
containerChild := button, containerBorderWidth := 10]
onClicked button (hello button)
onDestroy window mainQuit
widgetShowAll window
mainGUI
As of early 2014, I wasn't able to use #heinrich-apfelmus answer in Mac OS X. This GLFW-b example (link) however worked.
So, ensure you have:
$ cabal install glfw-b
and, if you tried Apfelmus' answer, you may need to
$ ghc-pkg list
$ ghc-pkg unregister GLFW-x.x.x.x
as both provide Graphics.UI.GLFW, and you will get an "Ambiguous module name 'Graphics.UI.GLFW'" from ghc. Then I just tried the sample program above and it worked (Mac OS X, 10.9, Mavericks)
Have you seen the GLFW as referenced http://plucky.cs.yale.edu/soe/software1.htm
More information on Haskell+GUI+OpenGL is available in this discussion:
http://www.haskell.org/pipermail/haskell-cafe/2011-May/091991.html