I want to perform image transformation in powershell. Basically I want to insert a circle that contains different ratios of red/blue/green and yellow (this varies from picture to picture) onto another picture.
Right now I've stubmeld upon PSImageTools (http://psimagetools.start-automating.com/), but as far as I can tell, they only allow me to overlay one picture on to another, but since the ratios of the 4 colours vary, I have to dynamically create a circle that can be mapped onto the existing picture.
How can I perform the hardcore pixel that I require, not just pasting 2 images together, but defining the colour of the single pixel in powershell?
The following makes edits to an image:
$imageOld = "C:\My\File.jpg"
$imagenew = "C:\My\File2.jpg"
# Load the System.Windows.Forms library
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$image = [System.Drawing.Image]::FromFile($imageOld)
$graphics = [System.Drawing.Graphics]::FromImage($image)
# 50% transparent white
$color = [System.Drawing.Color]::FromArgb(128, 255, 255, 255)
$brush = New-Object System.Drawing.SolidBrush($color)
# Draw a 500px circle located at (300, 300)
$graphics.FillEllipse($brush, 300, 300, 500, 500)
$image.Save($imageNew)
Related
I have an imageviewer with a couple images, When i zoom in the first image and wanna see the right side of the image. The folowing image is overlapping the inzooming image. This is very annoying. Is there a way how i can set the zoom in image on the front.
How can i set the zoomed image always on front.
See picture https://i.stack.imgur.com/5f5JZ.jpg
My imageviewer is in a container
Image red ;
red = EncodedImage.create("/HW_Delfzijl_Waddenzee_Oost.jpg");
Image blue = Image.createImage(500, 500, 0xff0000ff);
Image red2 = Image.createImage(500, 500, 0xffff0000);
Image List1[]= new Image [3];
List1[0] = red;
List1[1] = blue;
List1[2] = red2;
iv = new ImageViewer();
iv.setWidth(500);
iv.setHeight(500);
iv.setImageList(new DefaultListModel<>(List1));
Container1 = BoxLayout.encloseY( Kaarten.AuvHW, AdvSpr,iv,
Up,progressbar);
I was able to reproduce this with the following code:
Form hi = new Form("ImageViewer", BoxLayout.y());
Image red = Image.createImage(2000, 800, 0xffff0000);
Image blue = Image.createImage(2000, 500, 0xff0000ff);
ImageViewer viewer = new ImageViewer();
viewer.setImageList(new DefaultListModel<>(red, blue));
hi.add(BoxLayout.encloseY(viewer, new Label("Dummy")));
hi.show();
The problem only happens if I stand on the blue image (the second one) scale it up and then try to move. It doesn't happen when moving from the red image to the blue.
I believe this is due to this method in the ImagaViewer code. Since background isn't painted the old image isn't cleaned up. We need to add a condition that disables that while dragging. I think changing the code in that method to this will fix the problem but it's a bit risky and might trigger flickering:
protected void paintBackground(Graphics g) {
// disable background painting for performance when zooming
if(imageDrawWidth < getWidth() || imageDrawHeight < getHeight() || panPositionX != 0) {
super.paintBackground(g);
}
}
I would suggest filing an issue so we can consider the options here as this isn't trivial. One partial workaround is to use:
viewer.setImageInitialPosition(ImageViewer.IMAGE_FILL);
Which minimizes the impact of the issue.
In iText 7.1.9 I am taking a pdf created programmatically (not via iText) and need to apply a transparent rectangle along the left side and bottom to ensure the no content exists within a predefined clear zone (for print).
The below code places the yellow rectangles correctly but the desired result is the for the yellow fill to be semi-transparent or not 100% opaque so that visual inspection will show the content that that intersects with the rectangle instead of the rectangle clipping the content.
var page = pdf.GetPage(1);
PdfCanvas canvas = new PdfCanvas(page);
canvas.SaveState();
canvas.SetFillColor(iText.Kernel.Colors.ColorConstants.YELLOW);
var pageHeight = page.GetPageSize().GetHeight();
var pageWidth = page.GetPageSize().GetWidth();
// left side
canvas.Rectangle(0, 0, 15, pageHeight);
// bottom
canvas.Rectangle(0, 0, pageWidth, 15);
canvas.Fill();
canvas.RestoreState();
I attempted to use a TransparentColor but canvas.SetFillColor won't accept a TransparentColor, are there any other options?
When we speak about low-level content stream instructions, color itself and transparency levels are specified separately in PDF syntax. The TransparentColor class that you speak about was designed to simplify lives of users who are less familiar with nuances of PDF syntax, but it it a higher-level class that you can use e.g. in layout module, and in your case you operate with the document on quite low level.
Long story short, to set color transparency you only need one additional line next to setting the color itself:
canvas.SetExtGState(new PdfExtGState().SetFillOpacity(0.5f));
So the code becomes:
var page = pdf.GetPage(1);
PdfCanvas canvas = new PdfCanvas(page);
canvas.SaveState();
canvas.SetFillColor(iText.Kernel.Colors.ColorConstants.YELLOW);
canvas.SetExtGState(new PdfExtGState().SetFillOpacity(0.5f));
var pageHeight = page.GetPageSize().GetHeight();
var pageWidth = page.GetPageSize().GetWidth();
// left side
canvas.Rectangle(0, 0, 15, pageHeight);
// bottom
canvas.Rectangle(0, 0, pageWidth, 15);
canvas.Fill();
canvas.RestoreState();
I have a 4-channel image (.png, .tif) like this one:
I am using OpenCV, and I would like to add padding of type BORDER_REFLECT around the flower. copyMakeBorder is not useful, since it adds padding to the edges of the image.
I can add certain padding if I split the image in bgr + alpha and apply dilate with BORDER_REFLECT option on the bgr image, but that solution spoils all the pixels of the flower.
Is there any way to perform a selective BORDER_REFLECT padding addition on a ROI defined by a binary mask?
EDIT:
The result I expect is something like (sorry I painted it very quickly with GIMP) :
I painted two black lines to delimit the old & new contour of the flower after the padding, but of course those lines should not appear in the final result. The padding region (inside the two black lines) must be composed by mirrored pixels from the flower (I painted it yellow to make it understandable).
A simple python script to resize the image and copy the original over the enlarged one will do the trick.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
imgpad[20:20+sh[0], 20:20+sh[1], :][img[:,:,3]==255] = img[img[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Here is the result
But that doesn't look very 'centered'. So I modified the code to detect and account for the offsets while copying.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
def get_roi(img):
cimg = img[:,:,3].copy()
contours,hierarchy = cv2.findContours(cimg,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#Remove the tiny pixel noises that get detected as contours
contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 10]
x,y,w,h = cv2.boundingRect(cnt)
roi=img[y:y+h,x:x+w]
return roi
roi = get_roi(img)
roi2 = get_roi(imgpad)
sh = roi.shape
sh2 = roi2.shape
o = ((sh2[0]-sh[0])/2, (sh2[1]-sh[1])/2)
roi2[o[0]:o[0]+sh[0], o[1]:o[1]+sh[1], :][roi[:,:,3]==255] = roi[roi[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Looks much better now
The issue has been already addressed and solved here:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/
I am writing a function that generates a movie mimicking a particle in a fluid. The movie is coloured and I would like to generate a grayscaled movie for the start. Right now I am using avifile instead of videowriter. Any help on changing this code to get grayscale movie? Thanks in advance.
close all;
clear variables;
colormap('gray');
vidObj=avifile('movie.avi');
for i=1:N
[nx,ny]=coordinates(Lx,Ly,Nx,Ny,[x(i),-y(i)]);
[xf,yf]=ndgrid(nx,ny);
zf=zeros(size(xf))+z(i);
% generate a frame here
[E,H]=nfmie(an,bn,xf,yf,zf,rad,ns,nm,lambda,tf_flag,cc_flag);
Ecc=sqrt(real(E(:,:,1)).^2+real(E(:,:,2)).^2+real(E(:,:,3)).^2+imag(E(:,:,1)).^2+imag(E(:,:,2)).^2+imag(E(:,:,3)).^2);
clf
imagesc(nx/rad,ny/rad,Ecc);
writetif(Ecc,i);
if i==1
cl=caxis;
else
caxis(cl)
end
axis image;
axis off;
frame=getframe(gca);
cdata_size = size(frame.cdata);
data = uint8(zeros(ceil(cdata_size(1)/4)*4,ceil(cdata_size(2)/4)*4,3));
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata];
frame.cdata = data;
vidObj = addframe(vidObj,frame);
end
vidObj = close(vidObj);
For your frame data, use rgb2gray to convert a colour frame into its grayscale counterpart. As such, change this line:
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata];
To these two lines:
frameGray = rgb2gray(frame.cdata);
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = ...
cat(3,frameGray,frameGray,frameGray);
The first line of the new code will convert your colour frame into a single channel grayscale image. In colour, grayscale images have all of the same values for all of the channels, which is why for the second line, cat(3,frameGray,frameGray,frameGray); is being called. This stacks three copies of the grayscale image on top of each other as a 3D matrix and you can then write this frame to your file.
You need to do this stacking because when writing a frame to file using VideoWriter, the frame must be colour (a.k.a. a 3D matrix). As such, the only workaround you have if you want to write a grayscale frame to the file is to replicate the grayscale image into each of the red, green and blue channels to create its colour equivalent.
BTW, cdata_size(3) will always be 3, as getframe's cdata structure always returns a 3D matrix.
Good luck!
I want to cut a circle out of an image using rmagick.
Here's an example of what I'd like to be able to accomplish:
-->
It seems like I want to use http://studio.imagemagick.org/RMagick/doc/draw.html#circle to cut a circle, and then clip_path to mask it, but the docs aren't very clear. Would anyone be able to point me in the right direction?
require 'rmagick'
im = Magick::Image.read('walter.jpg').first
circle = Magick::Image.new 200, 200
gc = Magick::Draw.new
gc.fill 'black'
gc.circle 100, 100, 100, 1
gc.draw circle
mask = circle.blur_image(0,1).negate
mask.matte = false
im.matte = true
im.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
im.write 'walter_circle.png'
This is how I would do it with Imagemagick and php:
// Canvas the same size as the final image
exec("convert -size 800x533 xc:white white.jpg");
// The mask
exec("convert -size 800x533 xc:none -draw \"fill black circle 400,265 400,50\" write_mask.png");
// Cut the whole out of the canvas
exec("composite -compose Dst_Out write_mask.png white.jpg -matte step.png");
// Put the canvas over the image and trim off excess white background
exec("convert IMG_5745.jpg step.png -composite -trim final.jpg");
You should be able to follow the process?
Cleanup tempory images afterwards - I tend to save the tempory images in a .miff format and then write a loop to delete all .miff images afterwards. Alternativly just leave them and if you use the same name for the tempory images they will be overwritten every time the code is run.