Примените фоновый цвет при аннотировании изображения текстом, используя Magick.Net
Я использую C# и Magick.Net, чтобы комментировать изображения следующим образом:
var text = "Variable text";
var img = new MagickImage("image.jpg");
img.FontPointsize = 50;
img.FillColor = new MagickColor(Color.White);
img.Annotate(text, Gravity.Northwest);
Аннотация работает, однако текст не всегда легко читается, так как он может сочетаться с изображением.
Руководство ImageMagick имеет полный раздел, предлагающий решения для этого:
Изложил ярлык
convert dragon.gif -gravity south \ -stroke '#000C' -strokewidth 2 -annotate 0 'Faerie Dragon' \ -stroke none -fill white -annotate 0 'Faerie Dragon' \ anno_outline.jpg
Draw Dim Box
convert dragon.gif \ -fill '#0008' -draw 'rectangle 5,128,114,145' \ -fill white -annotate +10+141 'Faerie Dragon' \ anno_dim_draw.jpg
(Я бы использовал этот метод, только если больше ничего не работает, потому что он требует явного определения ширины и высоты прямоугольника.)
Undercolor Box
convert dragon.gif -fill white -undercolor '#00000080' -gravity South \ -annotate +0+5 ' Faerie Dragon ' anno_undercolor.jpg
Составная метка
convert -background '#00000080' -fill white label:'Faerie Dragon' miff:- |\ composite -gravity south -geometry +0+3 \ - dragon.gif anno_composite.jpg
Авторазмер заголовка
width=`identify -format %w dragon.gif`; \ convert -background '#0008' -fill white -gravity center -size ${width}x30 \ caption:"Faerie Dragons love hot apple pies\!" \ dragon.gif +swap -gravity south -composite anno_caption.jpg
Необычная этикетка
convert -size 100x14 xc:none -gravity center \ -stroke black -strokewidth 2 -annotate 0 'Faerie Dragon' \ -background none -shadow 100x3+0+0 +repage \ -stroke none -fill white -annotate 0 'Faerie Dragon' \ dragon.gif +swap -gravity south -geometry +0-3 \ -composite anno_fancy.jpg
Любой из вышеперечисленных подходов будет хорошо для меня. Тем не менее, я не могу найти необходимую функциональность в.Net API. Например, я пытался установить BackgroundColor перед вызовом Annotate. Это не произвело никакого эффекта:
img.BackgroundColor = new MagickColor(Color.Black);
Я хотел бы получить несколько советов о том, как реализовать любой метод, который повышает удобочитаемость текста аннотации, используя Magick.Net.
3 ответа
В итоге я реализовал опцию Composited Label следующим образом:
var text = "Variable text";
var img = new MagickImage("image.jpg");
using (var imgText = new MagickImage())
{
imgText.FontPointsize = 50;
imgText.BackgroundColor = new MagickColor(Color.Black);
imgText.FillColor = new MagickColor(Color.White);
imgText.Read("label:" + text);
img.Composite(text, Gravity.Northwest);
}
Хитрость заключается в том, чтобы "прочитать" изображение, но предоставить label:
запись вместо имени файла. Как только это будет сделано, мы можем просто скомбинировать сгенерированное изображение с оригинальным.
Помимо добавления черного фона к текстовой аннотации, этот код дает тот же результат, что и тот, который размещен в вопросе.
Просто еще один способ, похожий на @user1942447
string textToAdd = "ultra wide text with /r/n multiline row";
var readSettings = new MagickReadSettings
{
Font = "Arial",
TextGravity = Gravity.Center,
BackgroundColor = MagickColors.Transparent,
Height = 200, // height of text box
Width = 300 // width of text box
};
using (var tImage = new MagickImage())
{
using (var caption = new MagickImage($"label:{textToAdd}", readSettings))
{
//image is your main image where you need to put text
image.Composite(caption, 10, 20, CompositeOperator.Over);
image.Write(AppContext.BaseDirectory + Guid.NewGuid() + ".png");
}
}
Размер текста будет изменяться автоматически в зависимости от размера текстового поля. Если вам нужен строгий размер шрифта, используйте свойство FontPointsize, но текст может выходить за границы.
Для всех, кто пытается выяснить, как разместить текст на изображениях.
Это похоже на код, который я использую для добавления текста к изображениям в Magick.NET.
Используйте этот код в качестве фрагмента LINQPad. Используйте пакет Nuge t Magick.NET-Q16-AnyCPU.
void Main()
{
TextRender();
}
public void TextRender()
{
//If you use a transparent color here, you won't see the text
var imageBackgroundColor = new MagickColor("White");
using (MagickImage image = new MagickImage(imageBackgroundColor, 400, 400))
{
var drawable = new DrawableText(0,10,"Line One\nLine Two\nLine Three");
var gravity = new DrawableGravity(Gravity.North);
var font = new DrawableFont("Arial");
var antialias = new DrawableTextAntialias(true);
var size = new DrawablePointSize(50);
var color = new DrawableFillColor(Color.Black);
//If needed
//var strokeColor = new DrawableStrokeColor(Color.White);
image.Annotate("Some annotation", Gravity.Center);
image.Draw(drawable, gravity, font, antialias, size, color);//, strokeColor);
var imageFileName = @"c:\temp\tempImage.jpg";
//Write the file to disk
image.Write(imageFileName);
//For use in linqpad only
//Load the written file from disk and show it in the Results window
var image2 = (Bitmap) Image.FromFile(imageFileName, true);
image2.Dump();
}
}
Это результат: