How to set no border when drawing background colored rectange? - pdfclown

Is there a way to set no border when drawing background-color filled rectangle? Or make border color match background-color filled rectange?
PrimitiveComposer primitiveComposer = new PrimitiveComposer(page);
{
BlockComposer blockComposer = new BlockComposer(primitiveComposer);
primitiveComposer.SetLineWidth(0.0f);
primitiveComposer.SetFillColor(DeviceRGBColor.Get(System.Drawing.Color.DarkGray));
primitiveComposer.DrawRectangle(new RectangleF(_boxMarginX, _boxMarginY, (page.Size.Width - (_boxMarginX * 2)), 205f), 0f);
primitiveComposer.FillStroke();
}

You use
primitiveComposer.FillStroke();
which is the command to fill and stroke a path. As you don't want the borders, i.e. you don't want to stroke, use
primitiveComposer.Fill();
instead.
By the way,
primitiveComposer.SetLineWidth(0.0f);
The PDF specification defines a line width of 0 to mean the smallest line the target device can render.

Related

iText 7 - How to fill a canvas rectangle with a transparent color

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();

NSBezierPath Stroke color is wrong

I want to draw a 1px wide border around my custom NSView in DrawRect with NSBezierPath:
BorderColor.Set();
var path = NSBezierPath.FromRect(theRect);
path.LineWidth = 1;
path.Stroke();
Now BorderColor is set to NSColor.Gray, which I can see while debugging has an RGBA color code: (127,127,127,255)
But the 1px wide border which appears on the screen gets this color: (194,194,194,255)
When I set the path.LineWidth to 3, than I can see the 3 lines, the middle with wrong color (194..), the 2 wings with color (135,135,135,255) - which is close enough to the wanted (127..) color to be ok.
When I use four piece of 1px wide rectangles for border instead, and Fill these 4 rects, I also get the (135..) color, which is ok again.
I can use this rectangle based solution, I'm only wondering:
Is there a way to achieve the correct color for a 1px wide border with NSBezierPath.Stroke?
Assuming you're setting the stroke color correctly (we don't see how BorderColor is set up) it might be the case that you're measuring the color value on screen, which - in particular for a thin line - might have been anti-aliased so you're not seeing the original color but the output of the anti-aliasing algorithm.
Set the width to something bigger like 10 and measure the color in the middle of the 'blob' to make sure you're not chasing anti-aliasing artefacts..

What's good algorithm for getting color to make text on image outstanding?

For instance, below image, a photo is background, and there is a character 'Iniesta' at the center of the photo.
But the character is some hard to read because the color is not good.
Is there any good algorithm for getting color to make character on image outstanding?
Instead of making a rectangular background (that indeed doesn't look very nice) you could use this trick:
Pick two contrasting colors (e.g. white and black)
Stroke the text using first color and a wide pen (e.g. 5 pixels)
Draw the text filled using the second color
If you cannot stroke the text with a wide pen an alternative is drawing the text multiple times with small offsets; e.g. (Python)
for dy in range(-3, 4):
for dx in range(-3, 4):
draw_text(color1, x+dx, y+dy, message)
draw_text(color2, x, y, message)
For example a one-pixel border would look like this...
Here's another idea: choose a box around your text area, or the whole image if it's relatively homogeneous in color. Now compute the average color in this area by summing up the color values and dividing by the number of pixels.
Now choose a color which contrasts well with this average color. For instance, you could use the simple formula (255-r,255-g,255-b) to get a contrasting color. However, this would fail if the average color is close to 128-gray, so you'd need to special-case on that.
Another way is to convert the average color into HSL or HSV color space, and then play with the hue; for instance, just add 180 to it, and/or invert the "lightness" (value/luminosity). Again, you'd need to special-case the grayscale (saturation close to 0) cases.
There are many approaches that differs for static and dynamic scene. I assume static image so i focus on that. here some basic approaches:
Paper area
clear space behind text with paper color and render text with ink color as you mentioned this is not cool for complex images.
Stroke,shadows,3D
render text with 2 colors. Inside with text color and stroke with contrast color to it. If you do not have the capability then you can render character with bigger font/boldness size in stroke color first and then overwrite with smaller font size with inside color +/- shift the position to center the fonts. The shifting method determine if you render stroke or shadow or even 3D text can be achieved like this
Transparency
Instead of render pixels of text by constant color add some color value to the original pixel color. You can also substract color or use alpha mixing instead ...
XOR
instead render pixel with color XOR the original color with another color or by white
This is how it looks like:
Here the source in VCL/C++:
void TMain::draw()
{
if (!_redraw) return;
// needed variables
AnsiString txt,a;
TColor c0=clBlack,c1=clWhite;
int tx=50,ty=50,tys=30,dty=tys*1.5;
int x,y,x0,x1,y0,y1,i,b;
// clear whole image
bmp->Canvas->Brush->Color=clBlack;
bmp->Canvas->FillRect(TRect(0,0,xs,ys));
// copy photo
bmp->Canvas->Draw(0,0,in);
// render texts ...
txt="Paper area ";
bmp->Canvas->Font ->Size=tys;
bmp->Canvas->Font ->Color=c1;
bmp->Canvas->Brush->Color=c0;
bmp->Canvas->Brush->Style=bsSolid;
bmp->Canvas->TextOutA(tx,ty,txt); ty+=dty;
txt="Stroke";
bmp->Canvas->Brush->Style=bsClear;
for (x=tx,y=ty,i=1;i<=txt.Length();i++)
{
a=txt[i];
// stroked char
bmp->Canvas->Font ->Size=tys+3;
bmp->Canvas->Font ->Color=c0;
bmp->Canvas->Font ->Style=TFontStyles()<<fsBold;
x0=bmp->Canvas->TextWidth(a);
y0=bmp->Canvas->TextHeight(a);
bmp->Canvas->TextOutA(x,y,a);
// inside char
bmp->Canvas->Font ->Size=tys;
bmp->Canvas->Font ->Color=c1;
bmp->Canvas->Font ->Style=TFontStyles();
x1=bmp->Canvas->TextWidth(a);
y1=bmp->Canvas->TextHeight(a);
bmp->Canvas->TextOutA(x+((x0-x1)>>1),y+((y0-y1)>>1),a);
// next char position
x+=x0;
} ty+=dty;
txt="Shadow/3D text";
bmp->Canvas->Brush->Style=bsClear;
bmp->Canvas->Font ->Size=tys;
bmp->Canvas->Font ->Color=c0;
for (i=0;i<5;i++)
bmp->Canvas->TextOutA(tx-i,ty+i,txt);
bmp->Canvas->Font ->Color=c1;
bmp->Canvas->TextOutA(tx,ty,txt); ty+=dty;
Graphics::TBitmap *tmp=new Graphics::TBitmap;
tmp->PixelFormat=pf32bit;
tmp->HandleType=bmDIB;
txt="Transparent";
tmp->Canvas->Brush->Style=bsSolid;
tmp->Canvas->Brush->Color=0x00000000; // max black
tmp->Canvas->Font ->Size=tys;
tmp->Canvas->Font ->Color=0x00808080; // color offset
x=bmp->Canvas->TextWidth(txt);
y=bmp->Canvas->TextHeight(txt);
tmp->SetSize(x,y);
tmp->Canvas->FillRect(TRect(0,0,x,y));
tmp->Canvas->TextOutA(0,0,txt);
union col { DWORD dd; BYTE db[4]; } *p0,*p1;
for (y0=0,y1=ty;y0<y;y0++,y1++)
{
p0=(col*)tmp->ScanLine[y0];
p1=(col*)bmp->ScanLine[y1];
for (x0=0,x1=tx;x0<x;x0++,x1++)
for (i=0;i<4;i++)
{
b=WORD(p0[x0].db[i])+WORD(p1[x1].db[i]);
if (b>255) b=255;
p1[x1].db[i]=b;
}
} ty+=dty;
txt="XOR";
tmp->Canvas->Brush->Style=bsSolid;
tmp->Canvas->Brush->Color=0x00000000; // max black
tmp->Canvas->Font ->Size=tys;
tmp->Canvas->Font ->Color=0x00FFFFFF; // max white
x0=bmp->Canvas->TextWidth(txt);
y0=bmp->Canvas->TextHeight(txt);
tmp->SetSize(x0,y0);
tmp->Canvas->FillRect(TRect(0,0,x0,y0));
tmp->Canvas->TextOutA(0,0,txt);
bmp->Canvas->CopyMode=cmSrcInvert;
bmp->Canvas->Draw(tx,ty,tmp); ty+=dty;
bmp->Canvas->CopyMode=cmSrcCopy;
delete tmp;
// render backbuffer
Main->Canvas->Draw(0,0,bmp);
_redraw=false;
}
it uses just VCL encapsulated GDI things so it should be clear enough...
bmp is backbuffer image
in is your image
tmp is temp image for custom combining the text and image

Fonts created in Hiero can't set the color with new Color(r,g,b,a); - LIBGDX

I generated some fonts in Hiero. If I set the font color with :
fontFPS.setColor(Color.YELLOW);
the text color it is drawn correctly.
But if I set it with
Color fpsColor = new Color(74f, 112f, 139f, 160f);
fontFPS.setColor(fpsColor);
then I only get white color with no alpha. What is the problem?
First of all float values inside that method should be from 0f to 1f. So your color should be (values I put in constructor are calculated by dividing your original values with 255)
Color fpsColor = new Color(0.29f, 0.43f, 0.54f, 0.66f);
Also you should enable blending like this (I'm not sure if you already did that)
Gdx.gl.glEnable(GL10.GL_BLEND);
Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)

How to fill color in nsbox on nsslider movement?

I want to fill color in an NSBox on slider movement.
I am using the following code.
-(IBAction)slider1move:(id)sender {
[self.box setFillColor:[NSColor colorWithCalibratedRed: ([self.slider1 floatValue])/255.0 green:0.0 blue:0.0 alpha:0.0]];
}
Please correct me. I have three sliders in my application with each correspond to red , green and blue color.
How do I fill the color in the box on slider movement based on the current value of slider.
Like if my slider showing value of 50 the box should be half filled with red color if it is for red color.
First, make sure you've met the requirements listed in NSBox's setFillColor: documentation:
Functional only when the receiver’s box type (boxType) is NSBoxCustom
and its border type (borderType) is NSLineBorder.
Assuming that's not the problem, a quick guess would be that you may need to call setNeedsDisplay: on the box to get it redrawn with the new color.
Look at Your color, You set fully transparent color - alpha to 0.0 that's why Your color it's not changing.
Change Your color to alpha 1.0 like this:
[NSColor colorWithCalibratedRed: ([self.slider1 floatValue])/255.0 green:0.0 blue:0.0 alpha:1.0]

Resources