Save Image which is inside a content control - wpf

I'm having a content control which have a image inside when im trying to save that image im getting a black image. What am i missing.
RenderTargetBitmap rtb = new RenderTargetBitmap((int)content1.ActualWidth, (int)content1.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(content1);
PngBitmapEncoder pnge = new PngBitmapEncoder();
pnge.Frames.Add(BitmapFrame.Create(rtb));
Stream stream = File.Create(DriveName + ":/OpenCV/Images/UI/LeftEdge.png");
pnge.Save(stream);
stream.Close();

Looks like your ContentControl hasn't been layouted when you try to render it.
Try to call UpdateLayout() on it.
If that doesn't do the trick try calling first Measure(), than Arrange() - also before rendering.

Have you tried something like this :
if (control.Type == WdContentControlType.wdContentControlPicture)
{
if (control.Range.InlineShapes.Count != 0)
{
// Clear previous shapes
foreach (InlineShape shape in control.Range.InlineShapes)
{
if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
{
shape.Delete();
}
}
// Add new shape
InlineShape img = control.Range.InlineShapes.AddPicture (valueToSet, false, true);
img.Width = 90;
img.Height = 90;
}
}

Related

Canvas not working when inside a for loop [duplicate]

I wanted to upload the image files, draw them into canvas, make changes and save it in the database. I tried to test the base64 value that the canvas image (Pic) returned, and it is blank. However, I see the result when I append the canvas (Pic) to the document. What am I doing wrong here?
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
// read contents of files asynchronously
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
var canvas = document.createElement("canvas");
var datauri = event.target.result,
ctx = canvas.getContext("2d"),
img = new Image();
img.onload = function() {
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
};
img.src = datauri;
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
document.body.appendChild(canvas); //picture gets uploaded
// Generate the image data
var Pic = canvas.toDataURL("image/png");
console.log(Pic); // => returns base64 value which when tested equivalent to blank
Pic = Pic.replace(/^data:image\/(png|jpg);base64,/, "")
// Sending image to Server
$.ajax({
// …
});
};
})(f);
reader.readAsDataURL(f);
}
}
My intuition says that everything from var imageData = … should go into the img.onload function.
That means, at the relevant part the code becomes:
img.onload = function() {
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
document.body.appendChild(canvas); //picture gets uploaded
// Generate the image data
var Pic = canvas.toDataURL("image/png");
console.log(Pic); // => returns base64 value which when tested equivalent to blank
Pic = Pic.replace(/^data:image\/(png|jpg);base64,/, "")
// Sending image to Server
$.ajax({
// …
});
};
img.src = datauri;
The reason is that the line
ctx.drawImage(img, 0, 0, width, height);
correctly executes after the image has been loaded. But unfortunately, you don’t wait for loading when this line gets executed:
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
and all subsequent lines.
The image needs to be loaded in order to draw it on the canvas. The canvas needs to contain the loaded image in order to call getImageData.
I found a better solution to get the base64 code
Instead of this line:
var Pic = canvas.toDataURL("image/png");
use this:
var Pic = canvas.toDataURL("image/png").split(',')[1];

Convert SVG to PNG/JPEG not working on FF [duplicate]

I am trying to convert an external svg icon to a base64 png using a canvas. It is working in all browsers except Firefox, which throws an error "NS_ERROR_NOT_AVAILABLE".
var img = new Image();
img.src = "icon.svg";
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL;
};
Can anyone help me on this please? Thanks in advance.
Firefox does not support drawing SVG images to canvas unless the svg file has width/height attributes on the root <svg> element and those width/height attributes are not percentages. This is a longstanding bug.
You will need to edit the icon.svg file so it meets the above criteria.
As mentioned, this is an open bug caused by limitations on what Firefox accepts as specification for SVG sizes when drawing to a canvas. There is a workaround.
Firefox requires explicit width and height attributes in the SVG itself. We can add these by getting the SVG as XML and modifying it.
var img = new Image();
var src = "icon.svg";
// request the XML of your svg file
var request = new XMLHttpRequest();
request.open('GET', src, true)
request.onload = function() {
// once the request returns, parse the response and get the SVG
var parser = new DOMParser();
var result = parser.parseFromString(request.responseText, 'text/xml');
var inlineSVG = result.getElementsByTagName("svg")[0];
// add the attributes Firefox needs. These should be absolute values, not relative
inlineSVG.setAttribute('width', '48px');
inlineSVG.setAttribute('height', '48px');
// convert the SVG to a data uri
var svg64 = btoa(new XMLSerializer().serializeToString(inlineSVG));
var image64 = 'data:image/svg+xml;base64,' + svg64;
// set that as your image source
img.src = img64;
// do your canvas work
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL;
};
}
// send the request
request.send();
This is the most basic version of this solution, and includes no handling for errors when retrieving the XML. Better error handling is demonstrated in this inline-svg handler (circa line 110) from which I derived part of this method.
This isn't the most robust solution, but this hack worked for our purposes. Extract viewBox data and use these dimensions for the width/height attributes.
This only works if the first viewBox encountered has a size that accurately can represent the size of the SVG document, which will not be true for all cases.
// #svgDoc is some SVG document.
let svgSize = getSvgViewBox(svgDoc);
// No SVG size?
if (!svgSize.width || !svgSize.height) {
console.log('Image is missing width or height');
// Have size, resolve with new SVG image data.
} else {
// Rewrite SVG doc
let unit = 'px';
$('svg', svgDoc).attr('width', svgSize.width + unit);
$('svg', svgDoc).attr('height', svgSize.height + unit);
// Get data URL for new SVG.
let svgDataUrl = svgDocToDataURL(svgDoc);
}
function getSvgViewBox(svgDoc) {
if (svgDoc) {
// Get viewBox from SVG doc.
let viewBox = $(svgDoc).find('svg').prop('viewBox').baseVal;
// Have viewBox?
if (viewBox) {
return {
width: viewBox.width,
height: viewBox.height
}
}
}
// If here, no viewBox found so return null case.
return {
width: null,
height: null
}
}
function svgDocToDataURL(svgDoc, base64) {
// Set SVG prefix.
const svgPrefix = "data:image/svg+xml;";
// Serialize SVG doc.
var svgData = new XMLSerializer().serializeToString(svgDoc);
// Base64? Return Base64-encoding for data URL.
if (base64) {
var base64Data = btoa(svgData);
return svgPrefix + "base64," + base64Data;
// Nope, not Base64. Return URL-encoding for data URL.
} else {
var urlData = encodeURIComponent(svgData);
return svgPrefix + "charset=utf8," + urlData;
}
}

WPF add custom tooltip for a Path

I am building dynamically more paths in a canvas, and i want to add a tooltip with more details about the path shape. But it looks like the tolltip appears only when i hover the path points. I want it to appear also when i hover the filled area or the contour of it.
PolyLineSegment polySeg = new PolyLineSegment(new Point[] { new Point(triangleX - 8, triangleY - 20), new Point(triangleX + 8, triangleY - 20) }, true);
PathFigure pathFig = new PathFigure(new Point(triangleX, triangleY), new PathSegment[] { polySeg }, true);
PathGeometry pathGeo = new PathGeometry(new PathFigure[] { pathFig });
pathGeo.Transform = new RotateTransform(angleOfTheTriangleInGrades, triangleX, triangleY);
Path path = new Path();
path.Data = pathGeo;
path.Fill = Brushes.Yellow;
var sp = new StackPanel();
sp.Children.Add(new TextBlock
{
Text = "aaa"
});
sp.Children.Add(new Button
{
Height = 20,
Width = 100,
Content = "bbbaaa"
});
path.ToolTip = sp;
pathList.Add(path);

Rotate multiple images in Javascript

I have background image on background of canvas. And i want to put another image on background image. SO i can rotate upward image in any direction. I am trying javascript code which is available on internet. But both images were rotated. I want to rotate only upward image with some angle.
/* Upload first image to 0,0 co-ordinate. */
ctx.beginPath();
var imageObj = new Image();
imageObj.onload = function()
{
ctx.drawImage(imageObj, 0, 0, 300, 150);
};
imageObj.src = 'C://Users//rajesh.r//Downloads//images//images.jpg';
options.ctx.fill();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ctx.beginPath();
ctx.translate(400,300);
ctx.rotate(2*Math.PI / 8);
var thumbImageObj = new Image();
thumbImageObj.onload = function()
{
ctx.drawImage(thumbImageObj, 0, 0, 120, 20);
};
thumbImageObj.src = 'C://Users//rajesh.r//Downloads//images//images.png';
ctx.fill();
I want some solution so i can rotate second image by some angle.
When you call rotate on your canvas, you're not rotating an individual image, but instead rotating the entire canvas. To only rotate the second image you need take advantage of the save and restore methods provided by the canvas API.
Here's an example, based off of the code that you shared:
// canvas setup
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
// 1st image
var imageObj = new Image();
imageObj.onload = function() {
ctx.drawImage(imageObj, 0, 0, 100, 100);
};
imageObj.src = 'https://s3.amazonaws.com/so-answers/image1.jpg';
// 2nd image
var thumbImageObj = new Image();
thumbImageObj.onload = function() {
// save current canvas state
ctx.save();
// perform transformation
ctx.translate(110,110);
ctx.rotate(20*Math.PI / 180);
ctx.drawImage(thumbImageObj, 0, 0, 100, 100);
// restore original canvas state (without rotation etc)
ctx.restore();
};
thumbImageObj.src = 'https://s3.amazonaws.com/so-answers/image2.jpg';
body {
overflow: hidden;
margin: 0;
padding: 0;
}
<canvas id="canvas"></canvas>

set size of a base64 image javascript - angularjs

I saw many answers but I didn't find a good solution for this:
I have a picture in my $scope.file = /9j/4VeIRXhpZgAASUkqAAgAAAAL [..]
And it size is 5217984 = 5 MB
But this picture is só big and my angular aplication/web service is not supporting it.
What have I to do? And how?
I'm trying to convert this 5 MB image to a image with 500 KB but I didn't get it. Can anyone help my please?
I don't know if it its possible, but I need a function in javascript to convert that 5MB image to a image with 500 KB for example, and I can riseze it.
And its everything right in my application when I put a image with 500 KB fir example.
var $scope.getData= function () {
var reader = new FileReader();
reader.onload = $('input[type=file]')[0].files;
var img = new Image();
img.src =(reader.onload[0].result);
img.onload = function() {
if(this.width > 640)
{
//Get resized image
img= imageToDataUri(this, 640, 480);
}
}
};
//Resize the image (in the example 640 x 480px)
function imageToDataUri(img, width, height) {
// create an off-screen canvas
const canvas = document.createElement('canvas'),
const ctx = canvas.getContext('2d');
// set its dimension to target size
canvas.width = width;
canvas.height = height;
// draw source image into the off-screen canvas:
ctx.drawImage(img, 0, 0, width, height);
// encode image to data-uri with base64 version of compressed image
return canvas.toDataURL();
}
If you have access to the encoded base64 just use this function:
$scope.getFileSize = function (base64encoded) {
try {
var encodedString = base64encoded.split(',')[1]
} catch (errorMsg) {
return false;
}
var decodedBase64 = atob(encodedString);
return decodedBase64.length;
};

Resources