Is it possible to have a roundRectangle with no border? The following code creates roundRectangles and rectangles with border sizes of 0f and 1f. For the roundRectangle there is still a visible border when the lineWidth is set to 0f, but this is not true for a rectangle with a border of 0f.
Here is the code I'm using:
magazine = new Document(PageSize.LETTER,0,0,0,0);
pdfw = PdfWriter.getInstance(magazine, new FileOutputStream("out.pdf"));
magazine.open();
canvas = pdfw.getDirectContent();
canvas.rectangle(0,0,600,750);
canvas.setColorFill(BaseColor.ORANGE);
canvas.fillStroke();
canvas.setColorStroke(BaseColor.BLACK);
canvas.setColorFill(BaseColor.GRAY);
canvas.setLineWidth(1f);
llx = 100;
lly = 100;
wid = 100;
hei = 100;
canvas.roundRectangle(llx,lly, wid, hei, 10);
canvas.fillStroke();
llx = 100;
lly = 210;
wid = 100;
hei = 100;
canvas.rectangle(llx,lly, wid, hei);
canvas.fillStroke();
canvas.setColorStroke(BaseColor.BLACK);
canvas.setColorFill(BaseColor.WHITE);
canvas.setLineWidth(0f);
llx = 210;
lly = 100;
wid = 100;
hei = 100;
canvas.roundRectangle(llx,lly, wid, hei, 10);
canvas.fillStroke();
llx = 210;
lly = 210;
wid = 100;
hei = 100;
canvas.rectangle(llx,lly, wid, hei );
canvas.fillStroke();
When you draw lines and shapes in PDF, you use path construction operators. The following method introduces an re (rectangle) operator to construct a rectangle.
canvas.rectangle(0,0,600,750);
iText also provides convenience methods. For instance: the following method introduces a sequence of m (move to), l (line to), c (curve to),... operators:
canvas.roundRectangle(llx,lly, wid, hei, 10);
As soon as you have constructed the path, you can use a path painting operator to actually draw something. iText has different fill(), stroke() and fillStroke() variations.
You are using this method:
canvas.fillStroke();
This means that you fill the path with the fill color and stroke the path with the stroke color. In your question, you indicate that you only want to fill the path (you want to color what's inside the rounded rectangle); you do not want to stroke it (you don't want to draw the border of the rounded rectangle).
This is easy to achieve. Just replace fillStroke() by fill():
canvas.fill();
Now you will only fill the rounded rectangle and not stroke its border.
Comment by mkl:
A line width of 0 shall denote the thinnest line that can be rendered at device resolution: 1 device pixel wide.
This is correct. It is a common misconception that changing the width of a line to 0 means that the line isn't drawn when invoking stroke(). If you don't want to see a line, the solution is simple: don't stroke it.
Related
I want to copy selected part of a raw image to another image
I get start and end position as percentage and by that I can calculate the start and end position in width
how can I copy that selected part to another raw image?
Assuming it's a Texture2D, you can do the following:
Calculate A texture start/end X (dX)
Create a new Texture2D (B), sized as dX and full Y
Call A.GetPixels()
Iterate on array copying pixels to new texture
Apply on new texture
Pseudo code:
var aPixels = aTexture.GetPixels();
var bWidth = endX - startX;
var bTexture = new Texture2D(bWidth, endY);
var bPixels = bTexture.GetPixels();
for (int x = startX; x < endX; x++)
{
for (int y = 0; y < endY; y++)
{
var aIndex = x + y * A.width;
var bIndex = (x - startX) + y * bWidth;
bPixels[bIndex] = aPixels[aIndex];
}
}
bTexture.Apply();
Note that my code quite possibly won't work; as I'm typing this on a mobile phone.
Usually, Image Processing is an expensive process for CPUs, so I don't recommend it in Unity,
But anyway, For your image and in this special case, I think you can crop your image by changing the Size and Offset of texture in material.
Update:
This is an example of what I mentioned:
You can calculate Tile and Offset based on the dragged mouse position on Texture. (Check Here)
I found this.
you can set start coordinates and width and height to GetPixels();
void Start () {
public Texture2D mTexture;
Color[] c = mTexture.GetPixels (startX, startY, width, height);
Texture2D m2Texture = new Texture2D (width, height);
m2Texture.SetPixels (c);
m2Texture.Apply ();
gameObject.GetComponent<MeshRenderer> ().material.mainTexture = m2Texture;
}
```
I'm trying to draw a rectangle to the very top left of a page using ITextSharp (5.5.13). I want to draw in the page margins. However, the rectangle is around 25 pixels too low. How can I draw the rectangle in the top left corner?
Below is how I'm adding the rectangle to the page:
using (PdfReader reader = new PdfReader(inputPdf.FullName))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(outputPdf.FullName, FileMode.Create)))
{
PdfContentByte contentByte = stamper.GetOverContent(1);
PdfDocument doc = contentByte.PdfDocument;
float X = 0.0f;
float Y = 0.0f;
float Height = Utilities.InchesToPoints(0.50f);
float Width = Utilities.InchesToPoints(0.50f);
float llx = (doc.Left - doc.LeftMargin) + X;
float lly = (doc.Top - doc.TopMargin) - (Height + Y);
float urx = (doc.Left - doc.LeftMargin) + Width + X;
float ury = (doc.Top - doc.TopMargin) - Y;
Rectangle rectangle = new Rectangle(llx, lly, urx, ury)
{
BackgroundColor = BaseColor.BLACK
};
contentByte.Rectangle(rectangle);
}
Below are the debug values for each aforementioned variable:
Whenever you use a PdfStamper, the PdfDocument you can retrieve from its parts does not contain sensible information, it merely is a dummy object.
Thus, don't try to determine the page size from that PdfDocument doc, instead use the appropriate methods or properties of your PdfReader reader, e.g.
/** Gets the crop box without taking rotation into account. This
* is the value of the /CropBox key. The crop box is the part
* of the document to be displayed or printed. It usually is the same
* as the media box but may be smaller. If the page doesn't have a crop
* box the page size will be returned.
* #param index the page number. The first page is 1
* #return the crop box
*/
virtual public Rectangle GetCropBox(int index)
I generate a 4x4 grid of squares with below code. They all draw in correct position, rows and columns, on canvas on stage.update(). But the x,y coordinates for all sixteen of them on inspection are 0,0. Why? Does each shape has it's own x,y coordinate system? If so, if I get a handle to a shape, how do I determine where it was drawn originally onto the canvas?
The EaselJS documentation is silent on the topic ;-). Maybe you had to know Flash.
var stage = new createjs.Stage("demoCanvas");
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
var square = new createjs.Shape();
square.graphics.drawRect(i*100, j*100, 100, 100);
console.log("Created square + square.x + "," + square.y);
stage.addChild(square);
}
}
You are drawing the graphics at the coordinates you want, instead of drawing them at 0,0, and moving them using x/y coordinates. If you don't set the x/y yourself, it will be 0. EaselJS does not infer the x/y or width/height based on the graphics content (more info).
Here is an updated fiddle where the graphics are all drawn at [0,0], and then positioned using x/y instead: http://jsfiddle.net/0o63ty96/
Relevant code:
square.graphics.beginStroke("red").drawRect(0,0,100,100);
square.x = i * 100;
square.y = j * 100;
I'm using com.google.zxing.qrcode.QRCodeWriter to encode data and com.google.zxing.client.j2se.MatrixToImageWriter to generate the QR Code image. On a 400x400 image, there is about a 52 pixel wide border around the code. I'd like this border to be narrower, maybe 15 pixels, but I don't see anything in the API for doing that. Am I missing something in the documenation? Or would I need to process the image myself?
For reference, here is an example 400x400 QR Code produced with the ZXing library:
The QR spec requires a four module quiet zone and that's what zxing creates. (See QUIET_ZONE_SIZE in QRCodeWriter.renderResult.)
More recent versions of ZXing allow you to set the size of the quiet zone (basically the intrinsic padding of the QR code) by supplying an int value with the EncodeHintType.MARGIN key. Simply include it in the hints Map you supply to the Writer's encode(...) method, e.g.:
Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 2); /* default = 4 */
If you change this, you risk lowering the decode success rate.
Even by setting EncodeHintType.MARGIN to 0, the algorithm that convert the QRCode "dot" matrix to pixels data can generate a small margin (the algorithm enforce a constant number of pixels per dots, so the margin pixel size is the remainder of the integer division of pixels size by QR-Code dot size).
However you can completely bypass this "dot to pixel" generation: you compute the QRCode dot matrix directly by calling the public com.google.zxing.qrcode.encoder.Encoder class, and generate the pixel image yourself. Code below:
// Step 1 - generate the QRCode dot array
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(1);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
QRCode qrCode = Encoder.encode(what, ErrorCorrectionLevel.L, hints);
// Step 2 - create a BufferedImage out of this array
int width = qrCode.getMatrix().getWidth();
int height = qrCode.getMatrix().getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] rgbArray = new int[width * height];
int i = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
rgbArray[i] = qrCode.getMatrix().get(x, y) > 0 ? 0xFFFFFF : 0x000000;
i++;
} }
image.setRGB(0, 0, width, height, rgbArray, 0, width);
The conversion of the BufferedImage to PNG data is left as an exercise to the reader. You can also scale the image by setting a fixed number of pixels per dots.
It's usually more optimized that way, the generated image size is the smallest possible. If you rely on client to scale the image (w/o blur) you do not need more than 1 pixel per dot.
HashMap hintMap = new HashMap();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
hintMap.put(EncodeHintType.MARGIN, -1);
no margin
UPDATE
Add dependencies (from comments)
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.0</version>
</dependency>
In swift you can:
let hints = ZXEncodeHints()
hints!.margin = NSNumber(int: 0)
let result = try writer.encode(code, format: format, width: Int32(size.width), height: Int32(size.height), hints: hints)
let cgImage = ZXImage(matrix: result, onColor: UIColor.blackColor().CGColor, offColor: UIColor.clearColor().CGColor).cgimage
let QRImage = UIImage(CGImage: cgImage)
My problem is that I need to generate a PNG image with a transparent background fixed to x * x pixels.
I find that whatever I do with EncodeHintType.MARGIN, these is always some unexpected margin.
After reading its source code, I find a way to fix my problem, this is my code. There is no margin in the output BufferedImage.
BufferedImage oriQrImg = getQrImg(CONTENT_PREFIX+userInfo, ErrorCorrectionLevel.L,BLACK);
BufferedImage scaledImg = getScaledImg(oriQrImg,REQUIRED_QR_WIDTH,REQUIRED_QR_HEIGHT);
private static BufferedImage getQrImg(String content, ErrorCorrectionLevel level, int qrColor) throws WriterException {
QRCode qrCode = Encoder.encode(content, level, QR_HINTS);
ByteMatrix input = qrCode.getMatrix();
int w=input.getWidth(),h=input.getHeight();
BufferedImage qrImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = qrImg.createGraphics();
qrImg = g2d.getDeviceConfiguration().createCompatibleImage(w,h, Transparency.BITMASK);
g2d.dispose();
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (input.get(x,y) == 1) {
qrImg.setRGB(x, y, qrColor);
}else{
qrImg.setRGB(x, y, Transparency.BITMASK);
}
}
}
return qrImg;
}
static BufferedImage getScaledImg(BufferedImage oriImg,int aimWidth,int aimHeight){
Image scaled = oriImg.getScaledInstance(aimWidth,aimHeight,SCALE_DEFAULT);
Graphics2D g2d = new BufferedImage(aimWidth,aimHeight, BufferedImage.TYPE_INT_RGB).createGraphics();
BufferedImage scaledImg = g2d.getDeviceConfiguration().createCompatibleImage(aimWidth,aimHeight, Transparency.BITMASK);
g2d.dispose();
scaledImg.createGraphics().drawImage(scaled, 0, 0,null);
return scaledImg;
}
The technique shown in a similar question is a rectangular bubble. How to draw one in an oval shape? i.e.:
I would do it in two iterations.
First get the context and begin a path. Fill an ellipse and then a custom path that encloses a triangle with three lines. I assumed the following dimensions: 70 width, 62 height. Override draw rect in a subclass of UIView and instantiate in a subclassed UIViewController:
-(void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(ctx, 0.0, 0.0, 1.0, 1.0);
CGContextFillEllipseInRect(ctx, CGRectMake(0.0, 0.0, 70.0, 50.0)); //oval shape
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 8.0, 40.0);
CGContextAddLineToPoint(ctx, 6.0, 50.0);
CGContextAddLineToPoint(ctx, 18.0, 45.0);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
}
Produces this in the iPhone simulator when added against a gray backdrop:
This second code example will almost duplicate what you produced above. I implemented this using flexible sizes that could be supplied to the UIView frame when you instantiate it. Essentially, the white portion of the speech bubble is drawn with a black stroke over lay to follow.
-(void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect aRect = CGRectMake(2.0, 2.0, (self.bounds.size.width * 0.95f), (self.bounds.size.width * 0.60f)); // set the rect with inset.
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); //white fill
CGContextSetRGBStrokeColor(ctx, 0.0, 0.0, 0.0, 1.0); //black stroke
CGContextSetLineWidth(ctx, 2.0);
CGContextFillEllipseInRect(ctx, aRect);
CGContextStrokeEllipseInRect(ctx, aRect);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, (self.bounds.size.width * 0.10), (self.bounds.size.width * 0.48f));
CGContextAddLineToPoint(ctx, 3.0, (self.bounds.size.height *0.80f));
CGContextAddLineToPoint(ctx, 20.0, (self.bounds.size.height *0.70f));
CGContextClosePath(ctx);
CGContextFillPath(ctx);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, (self.bounds.size.width * 0.10), (self.bounds.size.width * 0.48f));
CGContextAddLineToPoint(ctx, 3.0, (self.bounds.size.height *0.80f));
CGContextStrokePath(ctx);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 3.0, (self.bounds.size.height *0.80f));
CGContextAddLineToPoint(ctx, 20.0, (self.bounds.size.height *0.70f));
CGContextStrokePath(ctx);
}
I have another way - however I dont have any time to properly explain it.
However, my example was written in .NET for use in a Windows application.
My version creates the entire speach bubble as 2D Polygon Mesh and is partially customizable. It is a single drawn path instead of multiple parts.
While our platforms are not the same - the technique uses common math routines and procedural loop. I believe the technique could be translated to other programming languages or platforms.
Private Sub Generate(ByVal Resolution As Integer, Optional ByVal SpeachPointerAngle As Integer = (45 * 3), Optional ByVal PointerBend As Decimal = 15)
'Generated the same way we create vector (wireframe) mesh for an Ellipse but...
'... at a predefined defined angle we create
'the size of the Pointer TIP/Corner portion of the speach bubble
'in relation to the EDGE of the ELLIPSE (average)
Dim SpeachPointerSize As Integer = 30
If PointerBend > 10 Then PointerBend = 10
If PointerBend < -10 Then PointerBend = -10
'as a variable offset that should be limited to max +/- -15 to 15 degrees relative to current angle as a safe range
'- were speach pointer angle determins which side the the pointer appears
Dim PointerOffsetValue As Decimal = PointerBend
Dim ActualPointerAngle As Decimal
'SpeachPointerAngle = 360 - SpeachPointerAngle ' adjust orientation so that 0 degrees is SOUTH
'Ellipse Size:
Dim Size_X As Decimal = 80
Dim Size_Y As Decimal = 50
If Resolution < 30 Then Resolution = 30
Dim Result As Vector2()
'size of each angle step based on resolution (number of vectors ) - Mesh Quality in otherwords.
Dim _Step As Decimal = 360 / Resolution
'Our current angle as we step through the loop
Dim _CurrentAngle As Decimal = 0
'rounded values
Dim _LastAngle As Decimal = 0
Dim _NextAngle As Decimal = _Step
Dim SpeachDrawn As Boolean = False ' prevent creating more than 1 point to be safe
Dim I2 As Integer = 0 'need a stepper because of skipped IDS
'build the ellipse mesh
For i = 0 To Resolution - 1
_LastAngle = _CurrentAngle - 15
_NextAngle = _CurrentAngle + 15
ActualPointerAngle = _CurrentAngle 'side
ActualPointerAngle += PointerOffsetValue ' acual angle of point
Dim EX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * Size_X
Dim EY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * Size_Y
'Point extrusion size ( trying to be even size all around )
Dim ExtrudeX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * (Size_X + SpeachPointerSize)
Dim ExtrudeY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * (Size_Y + SpeachPointerSize)
'is Pointer angle between Last and Next?
If SpeachPointerAngle > _LastAngle And SpeachPointerAngle < _NextAngle Then
If (SpeachDrawn = False) Then
' the point for the speachbubble tip
Array.Resize(Result, I2 + 1)
Result(I2) = New Vector2(ExtrudeX, ExtrudeY)
SpeachDrawn = True
I2 += 1
Else
'skip
End If
Else
'normal ellipse vector
Array.Resize(Result, I2 + 1)
Result(I2) = New Vector2(EX, EY)
I2 += 1
End If
_CurrentAngle += _Step
Next
_Vectors = Result
End Sub
The above code generated this - drawn to a bitmap using GDI+ [DrawPolygon/FillPolygon]:
https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash4/380262_10151202393414692_590995900_n.jpg
(Sorry - I can't post the image here directly as I have never posted here before. I don't have the reputation yet )
This is a Primitive in a Graphics Assembly I am developing for .NET which uses my own Vector2.
This speach bubble supports transparency when drawn - as it is a single polygon shape instead of multiple shapes.
Basically we draw an ellipse programatically and then extrude a speach point out on a desired side of the ellipse.
A similar approach could be applied using PointF structures instead.
All shapes in the code are generated around Origin 0,0.
Arrays are also resized incrementally as vectors are added prevent gaps in the array.
EG - the center of the speach bubble is Origin 0.0.
I apologize for not explaining my code properly - I just don't have the time.
But it probably isnt too hard to understand.