poi 4.1.2 Bullets will be lost when the slide is converted to a picture - apache-poi

I'm trying to convert every slide of pptx into an image through poi. For example, a text box with bullets in it is a user-defined image. The picture data was lost during conversion。
source file:
image:
public static void saveImg(int width, int height, XSLFSlide slide) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = image.createGraphics();
graphics2D.setPaint(Color.white);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
slide.draw(graphics2D);
String filename = "1.png";
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Administrator.DESKTOP-L8G4GEP\\Desktop\\ppt-pic\\" + filename)) {
ImageIO.write(image, "png", outputStream);
fileOutputStream.write(outputStream.toByteArray());
fileOutputStream.flush();
graphics2D.dispose();
} catch (Exception e) {
e.printStackTrace();
}
}

Related

Control image placement on JTextPane

I am able to add ImageIcons to a JTextPane, but when I add them they show up in the center of the JTextPane. I can't find a way to control where they are placed on the JTextPane. Can someone please help me with this?
This method is making the JTextPane:
private void loadTextPanel(JPanel contentPane) {
chatLogPanel = new JPanel();
chatLogPanel.setLayout(null);
EmptyBorder eb = new EmptyBorder(new Insets(10, 10, 10, 10));
DefaultStyledDocument document = new DefaultStyledDocument();
chatLog = new JTextPane(document);
chatLog.setEditorKit(new WrapEditorKit());
chatLog.setBorder(eb);
chatLog.setMargin(new Insets(5, 5, 5, 5));
chatLogScrollPane = new JScrollPane(chatLog);
addComponent(chatLogPanel, chatLogScrollPane, 0, 0, 500, 240);
addComponent(contentPane, chatLogPanel, 0, 40, 500, 240);
}
This is the code I'm using to add a string to the Panel:
private static void appendToChatLog(JTextPane tp, String msg, Color c) {
chatLog.setEditable(true);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, Integer.valueOf(3));
int len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
chatLog.setEditable(false);
}
And this is what I'm currently using to add the image to the JTextPane:
BufferedImage image = generateBufferedImage(message.getImage());
Icon icon = new ImageIcon(image);
StyleContext context = new StyleContext();
StyledDocument document = (StyledDocument) chatLog.getDocument();
Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
JLabel label = new JLabel(icon);
StyleConstants.setComponent(labelStyle, label);
try {
document.insertString(document.getLength(), "Ignored", labelStyle);
} catch (BadLocationException badLocationException) {
badLocationException.printStackTrace();
}
To insert a component to a JTextPane, and display it like a character, use the insertComponent method.
To insert an Icon instead, use the insertIcon method.
Quite intuitive isn't it ;)

JavaFX - Create semi circle with start and end angle

How to create semi circle with adjustable start and end angle in JavaFX. I tried to use Arc or ArcTo but it never gives me what I need. Is there any easy solution to create it?
How it should look like:
A quick solution would be to create an outer circle, an inner circle, 2 lines and use Shape.subtract to create a new shape:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Pane root = new Pane();
double dist = 10;
double outerRadius = 100;
double innerRadius = 50;
Circle outerCircle = new Circle();
outerCircle.setRadius(outerRadius);
Circle innerCircle = new Circle();
innerCircle.setRadius(innerRadius);
Line topLeftBottomRightLine = new Line(-outerRadius, -outerRadius, outerRadius, outerRadius);
topLeftBottomRightLine.setStrokeWidth(dist);
Line bottomLeftTopRightLine = new Line(-outerRadius, outerRadius, outerRadius, -outerRadius);
bottomLeftTopRightLine.setStrokeWidth(dist);
Shape shape = Shape.subtract(outerCircle, innerCircle);
shape = Shape.subtract(shape, topLeftBottomRightLine);
shape = Shape.subtract(shape, bottomLeftTopRightLine);
shape.setStroke(Color.BLUE);
shape.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3));
shape.relocate(300, 100);
root.getChildren().addAll(shape);
Scene scene = new Scene(root, 800, 400);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Similarly you can create only parts of the shape by using an arc and subtracting an inner circle from it.

JavaFX: setting background color for Text controls

I'm using a TextFlow and some Text items to show a styled text, but i cant find a way to set a simple background color for the Text items.
I can set the fill color and font but it does not have a java method or css property that sets its background color.
Based on this solution, this is a quick implementation of a method to provide background coloring for all the Text nodes within a FlowPane, using CSS and the ability to set a series of paint values separated by commas (as much as Text items) and insets for each one of them:
private FlowPane flow;
private Scene scene;
#Override
public void start(Stage primaryStage) {
Text text0 = new Text("These are several ");
Text text1 = new Text("Text Nodes ");
Text text2 = new Text("wrapped in ");
Text text3 = new Text("a FlowPane");
text0.setFill(Color.WHEAT);
text0.setFont(new Font("Times New Roman", 20));
text1.setFill(Color.WHITE);
text1.setFont(new Font("Verdana", 32));
text2.setFill(Color.WHITESMOKE);
text2.setFont(new Font("Arial", 24));
text3.setFill(Color.WHITESMOKE);
text3.setFont(new Font("Arial", 18));
flow = new FlowPane(text0, text1, text2, text3);
scene = new Scene(flow, 300, 200);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
setBackgroundColors();
flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());
}
private void setBackgroundColors(){
final Bounds out = flow.getBoundsInLocal();
final StringBuilder sbColors = new StringBuilder();
final StringBuilder sbInsets = new StringBuilder();
AtomicInteger cont = new AtomicInteger();
flow.getChildrenUnmodifiable().forEach(n->{
sbColors.append("hsb(")
.append((((double)cont.get())/((double)flow.getChildren().size()))*360d)
.append(", 60%, 90%)");
Bounds b = ((Text)n).getBoundsInParent();
sbInsets.append(b.getMinY()).append(" ");
sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()).append(" ");
sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
sbInsets.append(b.getMinX());
if(cont.getAndIncrement()<flow.getChildren().size()-1){
sbColors.append(", ");
sbInsets.append(", ");
}
});
flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
This will lead to this:
and after resizing the scene:
EDIT
Based on the OP request of using a TextFlow layout instead of a FlowPane, since Text nodes can be spanned over several lines within a TextFlow, the given solution will no longer be valid, as the bounding box of each text node will overlap others.
As a workaround, we can split the Text nodes in single word Text nodes, while keeping the same background color for those in the same original phrase.
I won't go into the splitting logic, but I will add a list of indices, where each index maps the text node with its index of background color.
private FlowPane flow;
private Scene scene;
private final List<Integer> indices=Arrays.asList(0,0,0,1,1,2,2,3,3);
#Override
public void start(Stage primaryStage) {
List<Text> text0 = Arrays.asList(new Text("These "), new Text("are "), new Text("several "));
List<Text> text1 = Arrays.asList(new Text("Text "), new Text("Nodes "));
List<Text> text2 = Arrays.asList(new Text("wrapped "), new Text("in "));
List<Text> text3 = Arrays.asList(new Text("a "), new Text("FlowPane"));
text0.forEach(t->t.setFill(Color.WHEAT));
text0.forEach(t->t.setFont(new Font("Times New Roman", 20)));
text1.forEach(t->t.setFill(Color.WHITE));
text1.forEach(t->t.setFont(new Font("Verdana", 32)));
text2.forEach(t->t.setFill(Color.WHITESMOKE));
text2.forEach(t->t.setFont(new Font("Arial", 24)));
text3.forEach(t->t.setFill(Color.WHITESMOKE));
text3.forEach(t->t.setFont(new Font("Arial", 18)));
flow = new FlowPane();
flow.getChildren().addAll(text0);
flow.getChildren().addAll(text1);
flow.getChildren().addAll(text2);
flow.getChildren().addAll(text3);
scene = new Scene(flow, 300, 200);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
setBackgroundColors();
flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());
}
private void setBackgroundColors(){
final Bounds out = flow.getBoundsInLocal();
final StringBuilder sbColors = new StringBuilder();
final StringBuilder sbInsets = new StringBuilder();
AtomicInteger cont = new AtomicInteger();
flow.getChildrenUnmodifiable().forEach(n->{
sbColors.append("hsb(")
.append((double)indices.get(cont.get())/(double)(indices.get(flow.getChildren().size()-1)+1)*360d)
.append(", 60%, 90%)");
Bounds b = ((Text)n).getBoundsInParent();
sbInsets.append(b.getMinY()).append(" ");
sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()-1).append(" ");
sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
sbInsets.append(b.getMinX());
if(cont.getAndIncrement()<flow.getChildren().size()-1){
sbColors.append(", ");
sbInsets.append(", ");
}
});
flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
This FlowPane now behaves as a TextFlow:
There is no background for Text objects. You'd either have to group it with a shape (rectangle, ellipse, etc) and set the color of that shape, or you could put the objects inside a StackPane and set the background color of the StackPane.

how to write byte[] to Image with Landscape or Portrait properties?

I have a code which converts byte[] to image but my code always writes in Landscape mode even original image was Portrait. How can I detect original image's Page Orientation and write new Image with this properties? Any suggestions?
public void SendFax(byte[] file, string fileName)
{
try
{
MemoryStream ms = new MemoryStream(file);
Image imgSave = Image.FromStream(ms);
Bitmap bmSave = new Bitmap(imgSave);
Bitmap bmTemp = new Bitmap(bmSave);
Graphics grSave = Graphics.FromImage(bmTemp);
grSave.DrawImage(imgSave, 0, 0, imgSave.Width, imgSave.Height)
//Save Image to physical path
bmTemp.Save("C:/..." + fileName);
imgSave.Dispose();
bmSave.Dispose();
bmTemp.Dispose();
grSave.Dispose();
}
catch (Exception ex)
{
throw ex;
}
}
Try with this. Check for img height and width and based on the comparison decide portrait/landscape
int srcWidth = image.Width;
int srcHeight = image.Height;
int thumbWidth = width;
int thumbHeight;
Bitmap bmp;
if (srcHeight > srcWidth)
{
thumbHeight = (srcHeight / srcWidth) * thumbWidth;
bmp = new Bitmap(thumbWidth, thumbHeight);
}
else
{
thumbHeight = thumbWidth;
thumbWidth = (srcWidth / srcHeight) * thumbHeight;
bmp = new Bitmap(thumbWidth, thumbHeight);
}

App using MonoTouch Core Graphics mysteriously crashes

My app launches with a view controller and a simple view consisting of a button and a subview. When the user touches the button, the subview is populated with scrollviews that display the column headers, row headers, and cells of a spreadsheet. To draw the cells, I use CGBitmapContext to draw the cells, generate an image, and then put the image into the imageview contained in the scrollview that displays the cells.
When I run the app on the iPad, it displays the cells just fine, and the scrollview lets the user scroll around in the spreadsheet without any problems. If the user touches the button a second time, the spreadsheet redraws and continues to work perfectly, If, however, the user touches the button a third time, the app crashes. There is no exception information display in the Application Output window.
My first thought was that the successive button pushes were using up all the available memory, so I overrode the DidReceiveMemoryWarning method in the view controller and used a breakpoint to confirm that this method was not getting called. My next thought was that the CGBitmapContext was not getting released and looked for a Monotouch equivalent of Objective C's CGContextRelease() function. The closest I could find was the CGBitmapContext instance method Dispose(), which I called, without solving the problem.
In order to free up as much memory as possible (in case I was somehow running out of memory without tripping a warning), I tried forcing garbage collection each time I finished using a CGBitmapContext. This made the problem worse. Now the program would crash moments after displaying the spreadsheet the first time. This caused me to wonder whether the Garbage Collector was somehow collecting something necessary to the continued display of graphics on the screen.
I would be grateful for any suggestions on further avenues to investigate for the cause of these crashes. I have included the source code for the SpreadsheetView class. The relevant method is DrawSpreadsheet(), which is called when the button is touched.
Thank you for your assistance on this matter.
Stephen Ashley
public class SpreadsheetView : UIView
{
public ISpreadsheetMessenger spreadsheetMessenger = null;
public UIScrollView cellsScrollView = null;
public UIImageView cellsImageView = null;
public SpreadsheetView(RectangleF frame) : base()
{
Frame = frame;
BackgroundColor = Constants.backgroundBlack;
AutosizesSubviews = true;
}
public void DrawSpreadsheet()
{
UInt16 RowHeaderWidth = spreadsheetMessenger.RowHeaderWidth;
UInt16 RowHeaderHeight = spreadsheetMessenger.RowHeaderHeight;
UInt16 RowCount = spreadsheetMessenger.RowCount;
UInt16 ColumnHeaderWidth = spreadsheetMessenger.ColumnHeaderWidth;
UInt16 ColumnHeaderHeight = spreadsheetMessenger.ColumnHeaderHeight;
UInt16 ColumnCount = spreadsheetMessenger.ColumnCount;
// Add the corner
UIImageView cornerView = new UIImageView(new RectangleF(0f, 0f,
RowHeaderWidth, ColumnHeaderHeight));
cornerView.BackgroundColor = Constants.headingColor;
CGColorSpace cornerColorSpace = null;
CGBitmapContext cornerContext = null;
IntPtr buffer = Marshal.AllocHGlobal(RowHeaderWidth * ColumnHeaderHeight * 4);
if (buffer == IntPtr.Zero)
throw new OutOfMemoryException("Out of memory.");
try
{
cornerColorSpace = CGColorSpace.CreateDeviceRGB();
cornerContext = new CGBitmapContext
(buffer, RowHeaderWidth, ColumnHeaderHeight, 8, 4 * RowHeaderWidth,
cornerColorSpace, CGImageAlphaInfo.PremultipliedFirst);
cornerContext.SetFillColorWithColor(Constants.headingColor.CGColor);
cornerContext.FillRect(new RectangleF(0f, 0f, RowHeaderWidth, ColumnHeaderHeight));
cornerView.Image = UIImage.FromImage(cornerContext.ToImage());
}
finally
{
Marshal.FreeHGlobal(buffer);
if (cornerContext != null)
{
cornerContext.Dispose();
cornerContext = null;
}
if (cornerColorSpace != null)
{
cornerColorSpace.Dispose();
cornerColorSpace = null;
}
}
cornerView.Image = DrawBottomRightCorner(cornerView.Image);
AddSubview(cornerView);
// Add the cellsScrollView
cellsScrollView = new UIScrollView
(new RectangleF(RowHeaderWidth, ColumnHeaderHeight,
Frame.Width - RowHeaderWidth,
Frame.Height - ColumnHeaderHeight));
cellsScrollView.ContentSize = new SizeF
(ColumnCount * ColumnHeaderWidth,
RowCount * RowHeaderHeight);
Size iContentSize = new Size((int)cellsScrollView.ContentSize.Width,
(int)cellsScrollView.ContentSize.Height);
cellsScrollView.BackgroundColor = UIColor.Black;
AddSubview(cellsScrollView);
CGColorSpace colorSpace = null;
CGBitmapContext context = null;
CGGradient gradient = null;
UIImage image = null;
int bytesPerRow = 4 * iContentSize.Width;
int byteCount = bytesPerRow * iContentSize.Height;
buffer = Marshal.AllocHGlobal(byteCount);
if (buffer == IntPtr.Zero)
throw new OutOfMemoryException("Out of memory.");
try
{
colorSpace = CGColorSpace.CreateDeviceRGB();
context = new CGBitmapContext
(buffer, iContentSize.Width,
iContentSize.Height, 8, 4 * iContentSize.Width,
colorSpace, CGImageAlphaInfo.PremultipliedFirst);
float[] components = new float[]
{.75f, .75f, .75f, 1f,
.25f, .25f, .25f, 1f};
float[] locations = new float[]{0f, 1f};
gradient = new CGGradient(colorSpace, components, locations);
PointF startPoint = new PointF(0f, (float)iContentSize.Height);
PointF endPoint = new PointF((float)iContentSize.Width, 0f);
context.DrawLinearGradient(gradient, startPoint, endPoint, 0);
context.SetLineWidth(Constants.lineWidth);
context.BeginPath();
for (UInt16 i = 1; i <= RowCount; i++)
{
context.MoveTo
(0f, iContentSize.Height - i * RowHeaderHeight + (Constants.lineWidth/2));
context.AddLineToPoint((float)iContentSize.Width,
iContentSize.Height - i * RowHeaderHeight + (Constants.lineWidth/2));
}
for (UInt16 j = 1; j <= ColumnCount; j++)
{
context.MoveTo((float)j * ColumnHeaderWidth - Constants.lineWidth/2,
(float)iContentSize.Height);
context.AddLineToPoint((float)j * ColumnHeaderWidth - Constants.lineWidth/2, 0f);
}
context.StrokePath();
image = UIImage.FromImage(context.ToImage());
}
finally
{
Marshal.FreeHGlobal(buffer);
if (gradient != null)
{
gradient.Dispose();
gradient = null;
}
if (context != null)
{
context.Dispose();
context = null;
}
if (colorSpace != null)
{
colorSpace.Dispose();
colorSpace = null;
}
// GC.Collect();
//GC.WaitForPendingFinalizers();
}
UIImage finalImage = ActivateCell(1, 1, image);
finalImage = ActivateCell(0, 0, finalImage);
cellsImageView = new UIImageView(finalImage);
cellsImageView.Frame = new RectangleF(0f, 0f,
iContentSize.Width, iContentSize.Height);
cellsScrollView.AddSubview(cellsImageView);
}
private UIImage ActivateCell(UInt16 column, UInt16 row, UIImage backgroundImage)
{
UInt16 ColumnHeaderWidth = (UInt16)spreadsheetMessenger.ColumnHeaderWidth;
UInt16 RowHeaderHeight = (UInt16)spreadsheetMessenger.RowHeaderHeight;
CGColorSpace cellColorSpace = null;
CGBitmapContext cellContext = null;
UIImage cellImage = null;
IntPtr buffer = Marshal.AllocHGlobal(4 * ColumnHeaderWidth * RowHeaderHeight);
if (buffer == IntPtr.Zero)
throw new OutOfMemoryException("Out of memory: ActivateCell()");
try
{
cellColorSpace = CGColorSpace.CreateDeviceRGB();
// Create a bitmap the size of a cell
cellContext = new CGBitmapContext
(buffer, ColumnHeaderWidth, RowHeaderHeight, 8,
4 * ColumnHeaderWidth, cellColorSpace, CGImageAlphaInfo.PremultipliedFirst);
// Paint it white
cellContext.SetFillColorWithColor(UIColor.White.CGColor);
cellContext.FillRect(new RectangleF(0f, 0f, ColumnHeaderWidth, RowHeaderHeight));
// Convert it to an image
cellImage = UIImage.FromImage(cellContext.ToImage());
}
finally
{
Marshal.FreeHGlobal(buffer);
if (cellContext != null)
{
cellContext.Dispose();
cellContext = null;
}
if (cellColorSpace != null)
{
cellColorSpace.Dispose();
cellColorSpace = null;
}
// GC.Collect();
//GC.WaitForPendingFinalizers();
}
// Draw the border on the cell image
cellImage = DrawBottomRightCorner(cellImage);
CGColorSpace colorSpace = null;
CGBitmapContext context = null;
Size iContentSize = new Size((int)backgroundImage.Size.Width,
(int)backgroundImage.Size.Height);
buffer = Marshal.AllocHGlobal(4 * iContentSize.Width * iContentSize.Height);
if (buffer == IntPtr.Zero)
throw new OutOfMemoryException("Out of memory: ActivateCell().");
try
{
colorSpace = CGColorSpace.CreateDeviceRGB();
// Set up a bitmap context the size of the whole grid
context = new CGBitmapContext
(buffer, iContentSize.Width,
iContentSize.Height, 8, 4 * iContentSize.Width,
colorSpace, CGImageAlphaInfo.PremultipliedFirst);
// Draw the original grid into the bitmap
context.DrawImage(new RectangleF(0f, 0f, iContentSize.Width, iContentSize.Height),
backgroundImage.CGImage);
// Draw the cell image into the bitmap
context.DrawImage(new RectangleF(column * ColumnHeaderWidth,
iContentSize.Height - (row + 1) * RowHeaderHeight,
ColumnHeaderWidth, RowHeaderHeight),
cellImage.CGImage);
// Convert the bitmap back to an image
backgroundImage = UIImage.FromImage(context.ToImage());
}
finally
{
Marshal.FreeHGlobal(buffer);
if (context != null)
{
context.Dispose();
context = null;
}
if (colorSpace != null)
{
colorSpace.Dispose();
colorSpace = null;
}
// GC.Collect();
//GC.WaitForPendingFinalizers();
}
return backgroundImage;
}
private UIImage DrawBottomRightCorner(UIImage image)
{
int width = (int)image.Size.Width;
int height = (int)image.Size.Height;
float lineWidth = Constants.lineWidth;
CGColorSpace colorSpace = null;
CGBitmapContext context = null;
UIImage returnImage = null;
IntPtr buffer = Marshal.AllocHGlobal(4 * width * height);
if (buffer == IntPtr.Zero)
throw new OutOfMemoryException("Out of memory: DrawBottomRightCorner().");
try
{
colorSpace = CGColorSpace.CreateDeviceRGB();
context = new CGBitmapContext
(buffer, width, height, 8, 4 * width, colorSpace,
CGImageAlphaInfo.PremultipliedFirst);
context.DrawImage(new RectangleF(0f, 0f, width, height),
image.CGImage);
context.BeginPath();
context.MoveTo(0f, (int)(lineWidth/2f));
context.AddLineToPoint(width - (int)(lineWidth/2f), (int)(lineWidth/2f));
context.AddLineToPoint(width - (int)(lineWidth/2f), height);
context.SetLineWidth(Constants.lineWidth);
context.SetStrokeColorWithColor(UIColor.Black.CGColor);
context.StrokePath();
returnImage = UIImage.FromImage(context.ToImage());
}
finally
{
Marshal.FreeHGlobal(buffer);
if (context != null){
context.Dispose();
context = null;}
if (colorSpace != null){
colorSpace.Dispose();
colorSpace = null;}
// GC.Collect();
//GC.WaitForPendingFinalizers();
}
return returnImage;
}
}
Not sure if this will solve your problem (I'm even newer to this than you are), but it seems from this answer that MonoTouch prefers a different paradigm for creating/releasing graphics contexts, along the lines of:
UIGraphics.BeginImageContext(rect.Size)
var context = UIContext.GetCurrentContext();
// ... do stuff ...
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
// ... do something with image ...
I don't know if it's releasing everything properly, but otherwise it seems to work.

Resources