I'm trying to rotate an image before composing it ontop of another, using RMagick with ruby. I can compose the overlaid image but when I try to rotate the image parts of the background are removed, like so...
Im not sure which CompositeOperator I should be using, or if this is the wrong approach all together?
image = Magick::Image.read("img.jpg").first
overlay = Magick::Image.read("./overlay.png").first
overlay.rotate!(9)
image.composite!(overlay, 100, 50, Magick::OverCompositeOp)
image.to_blob
Before rotating set your background to none:
overlay.background_color = "none"
Other possible methods to use after the rotation:
img.transparent_chroma(low, high, opacity=TransparentOpacity, invert=false)
img.transparent(color, opacity=TransparentOpacity)
so in your case:
overlay.transparent!("white")
you need to set the image transparency with the :opacity parameter
http://alternateidea.com/blog/articles/2005/9/19/custom-image-overlays-with-rmagick
http://www.ruby-forum.com/topic/119556
http://www.rhinocerus.net/forum/lang-ruby/63271-transparent-image-using-rmagick.html
RMagick: Convert CMYK EPS to RGB PNG maintaining transparent background
Related
tl;dr: How can I use RMagick to rotate an image at a given point.
I created a website which allows user to manipulate 2 images online and composite these images on the server side to a single image.
I use regular css transform: rotate() for rotation on the client side.
On the server side I'm rotating the image using RMagick's rotate! method but the results differ from the web version.
(Presumably because of an origin issue (e.g. at which point of the image the rotation takes place)).
The web version rotates at the center of the image (transform-origin: 50% 50%). Unfortunately RMagick doesn't by default.
I read through the RMagick docs and found affine_transform which accepts a matrix and transforms the image. Is this the right method to use, if so how? I tried passing the css-matrix to that function but it doesn't work.
Somewhere in the RMagick documentation I read that Magick::Image#rotate accepts 3 parameters (degree, originX, originY) but my version says that it only accepts 2 parameters (and actually requires the second parameter to be a string...).
My code:
require 'rmagick'
include Magick
#label = Label.last
image = #label.image
json = #label.processing
image.background_color = "none"
image.resize!(json["size"]["width"], json["size"]["height"])
# how can I set the rotation origin to the center of the image?
image.rotate!(json["rotation"].to_i)
overlay.composite!(image, json["position"]["x"], json["position"]["y"],
Magick::OverCompositeOp)
overlay.write("output5.png")
The output I'm currently getting is this. The blue square is actually imagein the code. The heart is overlay.
My desired output looks like this: (Ignore background, border and controls)
If I don't use rotation at all, both images are identically. That's why I assume it's an rotation issue. Both images are equally in width and height.
edit: Apparently only Magick::RVG::Image accepts the originX & originY parameters I mentioned above. Still not able to transform the current image into a RVG Image. It might solve the issue if I can transform my Magick::Image into Magick::RVG::Image.
Okay I've found a solution for this problem. I have to use RVG which is a module to create vector graphics.
The #rotate(degree, originX, originY) method is defined in the RVG::Image class so I had to wrap my Magick::Image object with:
require 'rvg/rvg'
image = RVG::Image.new(magick_image, width, height, x, y)
canvas = RVG.new(width, height)
canvas.use image
overlay.composite!(canvas.draw, ...)
Writing this on mobile, I will add a detailed answer asap.
I'm making a game were you can set the background image yourself.
The selected image is resized to make it fit the purpose, and then i want to load the picture into pygame.
I've something like:
image = Image.open('file')
image.thumbnail(size, Image.ANTIALIAS)
And now I want to load image into pygame.
of course I can use:
image.save(outfile, "JPEG")
background = pygame.image.load('outfile')
Is there a nice way without having to save the image to my hard drive?
Or is it possible that pygame resizes the image?
You can use pygame.transform.scale() to resize an image:
pygame.transform.scale()
resize to new resolution
scale(Surface, (width, height), DestSurface = None) -> Surface
Resizes the Surface to a new resolution. This is a fast scale operation that does not sample the results.
An optional destination surface can be used, rather than have it create a new one. This is quicker if you want to repeatedly scale something. However the destination must be the same size as the (width, height) passed in. Also the destination surface must be the same format.
So you don't have to use PIL.
am using fabricjs library to crop images, i set freedrawing property to true to draw on images. how can i make this drawing transparent so the image still appear ?
Thanks
In Matlab, when I use
imshow('trees.tif')
it displays an RGB image, but when I use these two functions
I=imread('trees.tif')
imshow(I)
it displays a gray scale image, and it's still the exact same image.
This only happens with TIFF images, because when I use it for a JPEG image like so:
I=imread('flower.jpg')
imshow(I)
it displays an RGB image, and it's the same thing as imshow('flower.jpg').
Can anyone please explain why the use of imread/imshow on TIFF images displays them in gray scale?
Load the color map too:
[I,cmap] = imread('trees.tif');
Display it with the map:
imshow(I,cmap)
Convert it to RGB:
Irgb = ind2rgb(I,cmap)
So you can display and manipulate it without the colormap:
imshow(Irgb)
imagesc(Irgb)
% etc.
Eye candy:
I'm writing a simple J2ME game that uses PNG images with 8-bit alpha channel. Problem: not all hardware supports full alpha transparency rendering. However, since my game is pretty static in nature (at the beginning, "sprites" are layed out onto background image, based on current screen size, and that's about it), I thought it would be possible to prerender those transparent images directly onto background during game initialization and use that later in game. I can't prerender them in Photoshop as their positions are not known in advance.
But, it seems there is no way to read the original alpha channel on devices that do not support semi-transparency as it gets resampled during PNG loading. Is there some library that can help with that? Or is it a good idea to store alpha channels separately (e.g. as separate 8-bit PNG images) and manually apply them?
Thanks!
PNG Images also have transparency support if you want to create transparent image then you have read RGB data along with alpha channels and process alpha
Image transPNG=Image.createImage("/trans.png"); //load the tranparent image
int rgbData[];
transPNG.getRGB(rgbData, 0,transPNG.getWidth(), 0, 0,transPNG.getWidth(), transPNG.getHeight());
Image tranparentImage=Image.createRGBImage(rgbData, width, height, true); //process alpha
transPNG=null;
Above code shows how to create the transparent image and use.
I cant promise this will help, but you can try this way of reading the alpha channel using standard methods from Java util.
BufferedImage image = ImageIO.read(new File(name));
int[] alpha = new int[1]; //containg alpha-value for one pixel.
image.getAlphaRaster().getPixel(x, y, alpha);
System.out.println(alpha[0]); //gives the alpha value for x,y