I'm trying to use im4java to generate sample image with text on image with the pattern. My code:
ConvertCmd convertCmd = new ConvertCmd();
IMOperation imOperation = new IMOperation();
imOperation.size(564, 564);
imOperation.tile(patternImg);
imOperation.background("none");
imOperation.stroke("black");
imOperation.strokewidth(2);
imOperation.fill("white");
imOperation.gravity("center");
imOperation.pointsize(40);
imOperation.border(3, 3);
imOperation.label(generateImageRequestDTO.getMainText());
imOperation.composite();
imOperation.addImage(absolutePathWorkDir + "/" + "test.jpg");
convertCmd.run(imOperation);
Which generate such script:
convert \
-size "564x564" -tile "/var/images/patterns/1.jpg" \
-background "none"-stroke "black" -strokewidth "2" -fill "white" \
-gravity "center"-pointsize "40" -border "3x3" -label "This is some text" \
-composite "/var/images/workdir/test.jpg"
Which is almost what I need. This is the code which I'm trying to generate:
convert \
-size "564x564" tile:"/var/images/patterns/1.jpg" \
-background "none"-stroke "black" -strokewidth "2" -fill "white" \
-gravity "center"-pointsize "40" -border "3x3" label:"This is some text" \
-composite "/var/images/workdir/test.jpg"
Basiclly
-tile ==> tile:
-label ==> label:
what i'm missing here?
Thank You a lot #emcconville ! That works!
Try adding the tile: & label: prefix to imOperation.addImage method. Like imOperation.addImage("tile:"+patternImg); – emcconville
Related
I'm using Vips to resize images via Shrine, hoping it's possible to use the Vips library to merge a layer of text on top of the image.
ImageProcessing::Vips.source(image).resize_to_fill!(width, height)
This code works great, how can I add a layer of text after resize_to_fill?
The goal is to write 'Hello world' in white text, with a CSS text-shadow in the center of the image.
I've tried writing something like this, but I'm only getting errors so far:
Vips\Image::text('Hello world!', ['font' => 'sans 120', 'width' => $image->width - 100]);
Your example looks like PHP -- in Ruby you'd write something like:
text = Vips::Image.text 'Hello world!', font: 'sans 120', width: image.width - 100
I made a demo for you:
#!/usr/bin/ruby
require "vips"
image = Vips::Image.new_from_file ARGV[0], access: :sequential
text_colour = [255, 128, 128]
shadow_colour = [128, 255, 128]
h_shadow = 2
v_shadow = 5
blur_radius = 10
# position to render the top-left of the text
text_left = 100
text_top = 200
# render some text ... this will make a one-band uchar image, with 0
# for black, 255 for white and intermediate values for anti-aliasing
text_mask = Vips::Image.text "Hello world!", dpi: 300
# we need to enlarge the text mask before we blur so that the soft edges
# don't get clipped
shadow_mask = text_mask.embed(blur_radius, blur_radius,
text_mask.width + 2 * blur_radius,
text_mask.height + 2 * blur_radius)
# gaussblur() takes sigma as a parameter -- approximate as radius / 2
shadow_mask = shadow_mask.gaussblur(blur_radius / 2) if blur_radius > 0.1
# make an RGB image the size of the text mask with each pixel set to the
# constant, then attach the text mask as the alpha
rgb = text_mask.new_from_image(text_colour).copy(interpretation: "srgb")
text = rgb.bandjoin(text_mask)
rgb = shadow_mask.new_from_image(shadow_colour).copy(interpretation: "srgb")
shadow = rgb.bandjoin(shadow_mask)
# composite the three layers together
image = image.composite([shadow, text], "over",
x: [text_left + h_shadow, text_left],
y: [text_top + v_shadow, text_top])
image.write_to_file ARGV[1]
Run like this:
$ ./try319.rb ~/pics/PNG_transparency_demonstration_1.png x.png
To make:
I work with tcl 8.6
I've got two tablelists (by Nehmeti):
set pfd(frMain) [frame $fr.frMain]
set pfd(bottomFr) [frame $pfd(frMain).bfr]
set pfd(panWin) [panedwindow $pfd(bottomFr).pw -showhandle 1 -orient vertical -sashpad 0 -sashrelief raised -sashwidth 2]
set pfd(frKlaffNeupkt) [frame $pfd(panWin).frKlaffNeupkt]
pack $pfd(frMesswerte) -anchor nw -expand 0 -fill both
pack $pfd(frKlaffNeupkt) -anchor nw -expand 0 -fill both
pack $pfd(panWin) -anchor nw -expand 1 -fill both
$pfd(panWin) add $pfd(frMesswerte) $pfd(frKlaffNeupkt)
set pfd(tali_mw) [tablelist::tablelist $pfd(frMesswerte).li.tali_mw \
-columns {0 "oid" l \
0 "status" l \
0 "art" l \
0 "sollTyp" l \
0 "Nr" l \
0 "Typ" l \
0 "Gst" l \
0 "Hz" r \
0 "V" r \
0 "S" r \
0 "Q" r \
0 "L" r \
0 "AK" l\
0 "LSEX" l \
0 "lfdNrGes" l}\
-exportselection 0 \
-labelbackground #EEEEEE \
-background white \
-labelfont $tableheadfont\
-font $tableinhfont\
-stretch 12\
-selectbackground $vmVConfig::setVar(activeBG) \
-selectforeground $vmVConfig::setVar(activeFG) \
-selectmode single\
-borderwidth 1 \
-labelborderwidth 1 \
-selectborderwidth 0 \
-tooltipaddcommand [::itcl::code $this tooltipAddCmd] \
-tooltipdelcommand [::itcl::code $this tooltipDelCmd] \
-xscrollcommand [list vmTkTools::configSB "h" $pfd(mw_scrx)]\
-yscrollcommand [list vmTkTools::configSB "v" $pfd(mw_scry)]]
set pfd(noteb) [iwidgets::notebook $pfd(frKlaffNeupkt).noteb]
pack $pfd(noteb) -anchor nw -expand 1 -fill both
set pfd(frKlaffungen) [$pfd(noteb) add -label Klaffungen]
set pfd(tali_klaff) [tablelist::tablelist $pfd(frKlaffungen).li.tali_klaff \
-columns {0 "oid" l 0 "Nr" l 0 "dX" r 0 "dY" r 0 "GwX" r 0 "GwY" r 0 "Rdz" r 0 "lfdNrGes" r}\
-exportselection 0 \
-labelbackground #EEEEEE \
-background white \
-labelfont $tableheadfont\
-font $tableinhfont\
-stretch 7\
-selectbackground $vmVConfig::setVar(activeBG) \
-selectforeground $vmVConfig::setVar(activeFG) \
-selectmode single\
-labelrelief groove \
-borderwidth 1 \
-labelborderwidth 1 \
-selectborderwidth 0 \
-xscrollcommand [list vmTkTools::configSB "h" $pfd(klaff_scrx)]\
-yscrollcommand [list vmTkTools::configSB "v" $pfd(klaff_scry)]]
Both tablelist have Bindings:
set body [$pfd(tali_mw) bodypath]
bind $body <Button-1> +[::itcl::code $this klickZeile %x %y %W]
bind $body <Double-1> +[::itcl::code $this doubleKlickMesswerte %x %y %W]
set body [$pfd(tali_klaff) bodypath]
bind $body <Button-1> [::itcl::code $this klickZeile %x %y %W]
The method klickZeile looks like this
itcl::body vmMaskHelmert::klickZeile {x y W} {
puts "klickZeile"
delCommonKreuz
foreach {pfad xC yC} [tablelist::convEventFields $W $x $y] {}
set row [$pfad containing $yC]
if {$row == -1} {
set row end
}
if {[string first "tali_mw" $W] != -1} {
# select the row
$pfd(tali_mw) activate $row
$pfd(tali_mw) selection clear 0 end
$pfd(tali_mw) selection set $row $row
anzeigePpMp
} else {
$pfd(tali_klaff) activate $row
$pfd(tali_klaff) selection clear 0 end
$pfd(tali_klaff) selection set $row $row
anzeigePpMp4Klaff
}
return
}
It seems, that the method klickZeile blocks my double click binding, the method doubleKlickMesswerte is not being called.
In klickZeile two corresponding rows in both tablelists are selected.
I tried to comment out the two blocks with "activate $row, selection clear 0 end and selection set $row $row". In that case, doubleKlickMesswerte is being called but unfortunately the method klickZeile doesn't work correctly. It seems that in that case the method selects the corresponding row for the row selected before.
So I've got two questions:
How can I prevent the method klickZeile from blocking the double click binding?
Or, if there is no way for this, what can I do, to make the method "klickZeile" work correctly without extra selection and activation?
Thanks for your help!
Mouse click events (at least single/double/triple) without modifiers (like Control) will all trigger when a bind to triple is set up and the user triple-clicks on the target element. The GUI cannot predict that another click is coming. It has to dispatch the single-click event first, followed by the double, then the triple.
Your best alternative is to use a modifier, such as a , because this is unique and does not depend on sequence, as long as the Control button is pressed first ;)
proc doClick { widget } {
puts "You clicked [$widget cget -text]"
}
proc doControlClick { widget } {
puts "You control-clicked [$widget cget -text]"
}
set label_1 [label .l1 -text "This is label 1"]
pack $label_1 -side top -fill both
bind $label_1 <Control-Button-1> { doControlClick %W }
bind $label_1 <Button-1> { doClick %W }
Is there a -level function in wand-py to adjust the levels of an image?
How do I access this ?
The -level operation, or MagickLevelImage C-API, does not currently exists in wand-py. However, wand.api makes adding support for this method very easy.
Example extending the wand.image.Image class:
from ctypes import c_void_p, c_double, c_int
from wand.api import library
from wand.image import Image
# Define C-API method signatures
library.MagickLevelImage.argtypes = [c_void_p, # wand
c_double, # black_point
c_double, # gamma
c_double] # white_point
library.MagickLevelImage.restype = c_int
class MyImage(Image):
def level(self, black, white, gamma=1.0):
# Assert black, gamma, & white are float types
# between 0.0 & 1.0.
# Both black & white values must be converted to
# QuantumRange percentages.
quantum = float(self.quantum_range)
return library.MagickLevelImage(self.wand,
black * quantum,
gamma,
white * quantum)
if __name__ == '__main__':
# convert rose: -level 20%,50% rose_level.png
with MyImage(filename='rose:') as image:
image.level(0.2, 0.5)
image.save(filename='rose_level.png')
How can I use a script such as Textcleaner within a Ruby-On-Rails application? Currently I'm using a custom paperclip processor where I use parameters similar to the script. Here is the has_attached_file line in my ActiveRecord:
has_attached_file :file, :style=> { :processors => [:text_cleaner] } }
Here is the Paperclip Processor:
module Paperclip
# Handles grayscale conversion of images that are uploaded.
class TextCleaner< Processor
def initialize file, options = {}, attachment = nil
super
#format = File.extname(#file.path)
#basename = File.basename(#file.path, #format)
end
def make
src = #file
dst = Tempfile.new([#basename, #format])
dst.binmode
begin
parameters = []
parameters << ":source"
parameters << "-auto-orient"
parameters << "-colorspace Gray"
#parameters << "-sharpen 0x1"
#parameters << "-type grayscale"
#parameters << "-contrast-stretch 0"
#parameters << "-clone 0"
#parameters << "-deskew 40%"
parameters << ":dest"
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
success = Paperclip.run("convert", parameters, :source => "#{File.expand_path(src.path)}[0]", :dest => File.expand_path(dst.path))
rescue PaperclipCommandLineError => e
raise PaperclipError, "There was an error during the grayscale conversion for #{#basename}" if #whiny
end
dst
end
end
end
Using paperclip I was able to add a Text Cleaner processor. I added it as a style in model via:
has_attached_file :file, :styles => { :clean => { :processors => [:text_cleaner] } }
And in /lib/paperclip_processors/text_cleaner.rb I have:
module Paperclip
# Handles grayscale conversion of images that are uploaded.
class TextCleaner < Processor
def initialize file, options = {}, attachment = nil
super
#format = File.extname(#file.path)
#basename = File.basename(#file.path, #format)
end
def make
src = #file
dst = Tempfile.new([#basename,#format])
dst.binmode
begin
parameters = '-respect-parenthesis \( :source -colorspace gray -type grayscale -contrast-stretch 0 \) \( -clone 0 -colorspace gray -negate -lat 15x15+5% -contrast-stretch 0 \) -compose copy_opacity -composite -fill "white" -opaque none +matte -deskew 40% -auto-orient -sharpen 0x1 :dest'
success = Paperclip.run('convert', parameters, :source => File.expand_path(#file.path), :dest => File.expand_path(dst.path))
rescue PaperclipCommandLineError => e
raise PaperclipError, "There was an error during the textclean conversion for #{#basename}" if #whiny
end
dst
end
end
end
I do this:
begin
image = MiniMagick::Image.open(params[:avatar_file].path)
unless image.valid?
raise nil
end
rescue
return head :not_acceptable
end
image.format 'jpeg'
image.resize '128x128'
image.write dir.to_s + current_user.id.to_s + '_128x128.jpg'
And after the resizing, if an image wasn't a square, one of the sides has 128 pixels and the second is smaller than the first.
I would like to make them the same size by cropping the center of the image.
As far as I know, "convert" utility of ImageMagick has "gravity center", but I'm not sure that this is what I need and how to use it with MiniMagick.
The answer is in the image.combine_options block:
begin
image = MiniMagick::Image.open(params[:avatar_file].path)
unless image.valid?
raise nil
end
rescue
return head :not_acceptable
end
image.format 'jpeg'
image.combine_options do |c|
c.resize '128x128^'
c.gravity 'center'
c.extent '128x128'
end
image.write dir.to_s + current_user.id.to_s + '_128x128.jpg'
ImageMagick variant:
convert stock.jpg -resize 128x128^ -gravity center -extent 128x128 result.jpg