Does iText honors color transparency? - itext

I'm using iText 5.2.1 and I tried to use the BaseColor constructor with alpha channel, that is
public BaseColor(final int red, final int green, final int blue, final int alpha)
but when I actually draw text or shapes it seems that the alpha channel isn't taken into account.
For example if I try this
Font f = ....;
f.setColor(new BaseColor(130, 130, 130, 50);
PdfContentByte cb = writer.getDirectContent();
ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("my text", f),
refPointX, refPointY, 0);
the text it's written with the color specified but without the alpha information, that is with the color with 100% opacity.
The same thing happens if I try to draw some shape and I specify a fill color with transparency.
In the book iText in Action second edition there's nothing about transparency in colors.
Am I wrong?

I've found something in itext mailing list, I tried and... works!
It's a undocumented feature. Anyway the following code does what I need:
PdfContentByte cb = writer.getDirectContent();
PdfGState gState = new PdfGState();
gState.setFillOpacity(0.1f);
cb.setGState(gState);
If a draw text or shapes, they have 10% opacity. With gState.setStrokeOpacity I can also set opacity on strokes.

Related

Anylogic: Adding text label to Rectangular Wall

Is it possible to add a text label on top of rectangular walls in Anylogic? I am trying to dynamically create rectangular walls using code and then adding labels. So far I am able to create the walls but the text label does not appear on top of the walls as I want it.
If you are creating walls dynamically I assume you also want to create your text dynamically.
There is a little trick in AnyLogic where you can view the code that gets created for you by AnyLogic discussed in this blog post
You can use the code snipped below to draw a Text object and add it to the presentation collection (which is needed for it to be displayed)
Font _text_Font = new Font("SansSerif", 0, 10 ); // Only needed if you don't have any text in your agent else _text_Font gets created for you.
ShapeText myProgramticallyCreatedText = new ShapeText(
SHAPE_DRAW_2D, true,170.0, 90.0, 0.0, 0.0,
black,"Programatically Created text",
_text_Font, ALIGNMENT_LEFT );
presentation.add(myProgramticallyCreatedText);
Here is the syntax for creating your
ShapeText(boolean ispublic, double x, double y, double rotation, java.awt.Color color, java.lang.String text, java.awt.Font font, TextAlignment alignment)
Constructs a 2D-only text shape with specific attributes.
ShapeText(ShapeDrawMode drawMode, boolean ispublic, double x, double y, double z, double rotation, java.awt.Color color, java.lang.String text, java.awt.Font font, TextAlignment alignment)
Constructs a text shape with specific attributes.
Depending on whether or not you have 3D or not you can rotate the text by changing the correct parameters
If you want to make it visible in 3d and also rotate it correctly you need to create a group, add the text to that group, then create a new group, and the group this new group and then rotate the first group. Like below
Font _text_Font = new Font("SansSerif", 0, 10 );
ShapeText myProgramticallyCreatedText = new ShapeText(
SHAPE_DRAW_2D3D, true,170.0, 90.0, 0.0, 0.0,
black,"Programatically Created text",
_text_Font, ALIGNMENT_LEFT );
ShapeGroup innerGroup = new ShapeGroup(this, SHAPE_DRAW_2D3D, true, 170.0, 20.0, 0.0, 0.0 , myProgramticallyCreatedText );
ShapeGroup outerGroup = new ShapeGroup(this, SHAPE_DRAW_2D3D, true, 170.0, 20.0, 0.0, 0.0 , innerGroup );
innerGroup.setRotationX(-PI/2 );
presentation.add(outerGroup);
(P.S. I figured all of this out using the trick from the blog post referenced above ;-) )
If it should show horizontally on top of the wall, just ensure it has the same x,y coordinates as the center of the wall and then set the z-coordinate higher than the wall height.
If you want to show it vertically (like a clock hanging from the wall), you need to set the xY coordinates carefully so it does not display inside the wall. Z coordinate half way of the wall height. And then you need to do a trick to turn the text: put it into a group and rotate the group. The example model "Airport terminal" does that, check it out

iText 7 Adding colored text and fill to a rectangle

I am trying to add colored text to a rectangle and fill color in the rectangle but the
text seems to be behind the rectangle and so is not visible even though I can select it.
Paragraph = new Paragraph("The quick brown fox");
PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
Rectangle rect = new Rectangle(ps.getWidth() - 90, ps.getHeight() - 100, 50, 50);
new Canvas(canvas, pdfDoc, rect)
.setFontColor(ColorConstants.WHITE)
.setFontSize(12)
.add(p);
canvas.rectangle(rect)
.setFillColor(ColorConstants.LIGHT_GRAY)
.fillStroke();
You first draw the text and then fill the rectangle. Thus, obviously the text ends up behind the rectangle.
Switch the order of your instructions, first fill the rectangle rect on your PdfCanvas canvas and then add the Paragraph p to the Canvas on canvas.

Unity 2D: dynamically create a hole in a image

I am using Unity 2D and I am trying to achieve this simple effect.
I am making a Candy Crush Saga - like game.
I have a grid with all the items. In every level the grid field can have different shapes, created at runtime (a dark grey area in the middle of the background).
The background is a still image (blue sky and green hills). When the pieces (for example a blue pentagon) fall down from the top they must be hidden until they enter the grid field area (dark grey); so in practice the background image (sky and hills) is no more a background, but is a foreground with a hole that is represented by the grey area. The grey field is composed as well by tiles from a sprite sheet.
I have prepared a picture, but I cannot load it here unfortunately yet. How can I achieve this effect in Unity?
The most simple solution would be to create all the static levels graphics already with the hole, but I do not want to create them because it is a waste of time and also a waste of memory, I want to be able to create this effect at runtime.
I was thinking about creating a dynamic bitmap mask for the hole shape using a sprite sheet. Then using this bitmap mask as a material for example to be applied to the image in the foreground and make a hole.
click on your texture in the unity editor
change "texture type" from "texture" to "advanced"
check the "read/write enabled" checkbox
change "format" form "automatic compressed" to "RGBA 32 bit"
i attached this component to a raw image (you can attach it to something else, just change the "RawImage image" part)
this will create a hole with dimensions 100x100 at position 10,10 of the image, so make sure that your texture is at least 110x110 large.
using UnityEngine;
using UnityEngine.UI;
public class HoleInImage : MonoBehaviour
{
public RawImage image;
void Start()
{
// this will change the original:
Texture2D texture = image.texture as Texture2D;
// use this to change a copy (and not the original)
//Texture2D texture = Instantiate(image.mainTexture) as Texture2D;
//image.mainTexture = texture;
Color[] colors = new Color[100*100];
for( int i = 0; i < 100*100; ++i )
colors[i] = Color.clear;
texture.SetPixels( 10, 10, 100, 100, colors );
texture.Apply(false);
}
}
EDIT:
hole defined by one or more sprites:
do the same for these sprites: (advanced, read/write enabled, RGBA 32 bit)
for example: if sprite is white and the hole is defined with black:
for( int i = 0; i < 100*100; ++i )
colors[i] = Color.clear;
change to:
Texture2D holeTex; // set this in editor, it must have same dimensions (100x100 in my example)
Color[] hole = holeTex.GetPixels();
for( int i = 0; i < 100*100; ++i )
{
if( hole[i] == Color.black ) // where sprite is black, there will be a hole
colors[i] = Color.clear;
}

How change the white skin face to dark skin face in iOS?

I need to change the white skin face to dark skin face...
For example American white face to African face(i.e color tone)...
I pick the color value of the pixel by digital color meter it gives the RGB value[red=101,green=63 and blue=43] for dark skin and for white skin it gives the RGB value as [red=253,green=210 and blue=176]...
Then i am setting that value in my code it gives the false result...
Here is my code...
-(UIImage*)customBlackFilterOriginal
{
CGImageRef imgSource=self.duplicateImage.image.CGImage;
CFDataRef m_DataRef1 = CGDataProviderCopyData(CGImageGetDataProvider(imgSource));
UInt8 *dataOriginal=(UInt8 *)CFDataGetBytePtr(m_DataRef1);
double lengthSource=CFDataGetLength(m_DataRef1);
NSLog(#"length::%f",lengthSource);
int redPixel;
int greenPixel;
int bluePixel;
for(int index=0;index<lengthSource;index+=4)
{
dataOriginal[index]=dataOriginal[index];
dataOriginal[index+1]= 101;
dataOriginal[index+2]= 63;
dataOriginal[index+3]=43;
}
NSUInteger width =CGImageGetWidth(imgSource);
size_t height=CGImageGetHeight(imgSource);
size_t bitsPerComponent=CGImageGetBitsPerComponent(imgSource);
size_t bitsPerPixel=CGImageGetBitsPerPixel(imgSource);
size_t bytesPerRow=CGImageGetBytesPerRow(imgSource);
NSLog(#"the w:%u H:%lu",width,height);
CGColorSpaceRef colorspace=CGImageGetColorSpace(imgSource);
CGBitmapInfo bitmapInfo=CGImageGetBitmapInfo(imgSource);
CFDataRef newData=CFDataCreate(NULL,dataOriginal,lengthSource);
CGDataProviderRef provider=CGDataProviderCreateWithCFData(newData);
CGImageRef newImg=CGImageCreate(width,height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorspace,bitmapInfo,provider,NULL,true,kCGRenderingIntentDefault);
return [UIImage imageWithCGImage:newImg];
}
please share any idea about the above color changing....
what mistake i did in the code?..
I am not an IPhone programmer so I can't test anything but some things are odd in your code:
Pixel size
When reading your data, you seem to assume you have a 32bits ARGB picture, did you validate it's the case?
CFDataGetBytePtr
According to the docs, it Returns a read-only pointer to the bytes of a CFData object., are you sure you're not looking for CFDataGetBytes which Copies the byte contents of a CFData object to an external buffer. In which case you'll have to allocate your buffer to contain width * height * bpp. Once you have this copy, you can manipulate it anyway you want to create the new picture.
Pixel Selection
According to your question, I seem to understand that you want to change skin color from White to Black. Your current code iterates over every pixel to change its color. You should evaluate the "distance" between the pixel color and what you're looking for, and if it's below a certain threshold process it. It might be easier to perform the operation in HSV than by dealing with RGB colors.

Objective-C RGB to HSB

Let's say I've got the colour FF0000, which is red. Finding a darker colour is easy, I just type maybe CC instead of the FF, but let's say I've got the colour AE83FC, which is a complicated colour, how the heck would I find a lighter or darker version of it automatically?
I figured the easy way to do this is to convert my RGB to HSB [Hue, Saturation, Brightness]
How would I do that in Objective-C?
Let's say I've got a RGB which is: 1.0, 0.0, 0.0. That's red.
CGFloat r = 1.0;
CGFloat g = 0.0;
CGfloat b = 0.0;
How would I convert that to HSB and then transform the colors and make it go back to RGB to I can use CGContextRGBSetFillColor?
Are there any HSB functions?
Please help. :)
First, please be aware that three numbers don't describe a color, three numbers together with a colorspace do. RGB isn't a colorspace, it's what's called a color model. There are lots of colorspaces with the RGB model. So ((1,0,0), sRGB) is a different color than ((1,0,0), Adobe RGB). Are you aware of how string encodings work, where a bunch of bytes by itself is not a string? It's a lot like that. It's also similar in that you're kind of asking for trouble whenever you want to look at the component values, because it's an opportunity for messing up the colorspace handling.
Sorry, cannot help myself. Anyway, I'll answer the question as if your original color was ((1,0,0), Generic RGB).
NSColor *color = [NSColor colorWithCalibratedRed:1 green:0 blue:0 alpha:1];
NSLog(#"hue! %g saturation! %g brightness! %g, [color hueComponent], [color saturationComponent], [color brightnessComponent]);
and on the other hand,
NSColor *color = [NSColor colorWithCalibratedHue:h saturation:s brightness:b alpha:1];
NSLog(#"red! %g green! %g blue! %g, [color redComponent], [color greenComponent], [color blueComponent]);
These fooComponent methods do not work with all colors, only those in two specific colorspaces, see docs. You already know you're good if you created the colors yourself with the methods above. If you have a color of unknown provenance, you can (attempt to) convert it to a colorspace in which you can use those component methods with -[NSColor colorUsingColorspaceName:].
There is no need to go all the way to HSB for this. If you want to find a darker version of a color, just multiply each R, G and B component with a number between 0 and 1, and you will get the same color, but darker.
Example: half intensity of AE83FC:
{0xAE, 0x83, 0xFC} * 0.5 =
{174, 131, 252} * 0.5 =
{87, 65, 126} =
{0x57, 0x41, 0x7E} => 57417E
In the same way, you can obtain brighter versions by multiplying with anything >1. The value of each component can't be larger than 255, so when that happens, you need to limit it to 255. That means that the color wont be exactly a brighter version of the same color, but probably close enough for your purposes.