Nativescript BitmapFactory resize does not work in iOS - ios

I am using the BitmapFactory plugin to rezize pictures to save them as thumnails
let mutable = BitmapFactory.makeMutable(imageSource);
let rotatedBitmap = BitmapFactory.asBitmap(mutable).dispose((bmp) =>
{
return bmp.resize("80,80");
});
in Android it works perfectly, but in iOS the image returned is not resized. I read in some issues that this is because the iOS uses the default scaling..?
does anybody knnow how to resize images to square thumbnaile with a given size ?
I use undermentioned function...
imageSource = imageSourceModule.fromFile(filepath);
try
{
var mutable = BitmapFactory.makeMutable(imageSource);
var ThumbBitmap = BitmapFactory.asBitmap(mutable).dispose((bmp) =>
{
var optisizestring = "25,25";
test = bmp.resize(optisizestring);
base64JPEG = test.toBase64(BitmapFactory.OutputFormat.JPEG, 75);
img = imageSource.fromBase64(base64JPEG);
resolve( "data:image/png;base64," + base64JPEG);
global.gc(); // tried with \ without garbage collection here
});
} catch(ex) { console.log("errds " + ex); resolve (null);}
(in the BitmapFactory-plugin) BitmapFactory.ios.js i changed the resize function
iOSImage.prototype._resize = function(newSize) {
var oldImg = this._nativeObject;
try {
var ns = CGSizeMake(newSize.width, newSize.height);
UIGraphicsBeginImageContext(ns);
var context = UIGraphicsGetCurrentContext();
oldImg.drawInRect(CGRectMake(0, 0,ns.width, ns.height));
return UIGraphicsGetImageFromCurrentImageContext();
}
finally
{
UIGraphicsEndImageContext();
}
};
// // [INTERNAL] _resize() Original
// iOSImage.prototype._resize = function(newSize) {
// var oldImg = this._nativeObject;
// try {
// var ns = CGSizeMake(newSize.width, newSize.height);
// UIGraphicsBeginImageContextWithOptions(ns, false, 0.0);
// oldImg.drawInRect(CGRectMake(0, 0,
// ns.width, ns.height));
// return new iOSImage(UIGraphicsGetImageFromCurrentImageContext());
// }
// finally {
// UIGraphicsEndImageContext();
// }
// };

Related

How to get PNG image data from a Canvas in Flutter?

I have a Flutter widget that accepts user input and draws to a canvas using a custom painter:
class SPPoint {
final Point point;
final double size;
SPPoint(this.point, this.size);
String toString() => "SPPoint $point $size";
}
class SignaturePadPainter extends CustomPainter {
final List<SPPoint> allPoints;
final SignaturePadOptions opts;
Canvas _lastCanvas;
Size _lastSize;
SignaturePadPainter(this.allPoints, this.opts);
ui.Image getPng() {
if (_lastCanvas == null) {
return null;
}
if (_lastSize == null) {
return null;
}
var recorder = new ui.PictureRecorder();
var origin = new Offset(0.0, 0.0);
var paintBounds = new Rect.fromPoints(_lastSize.topLeft(origin), _lastSize.bottomRight(origin));
var canvas = new Canvas(recorder, paintBounds);
paint(canvas, _lastSize);
var picture = recorder.endRecording();
return picture.toImage(_lastSize.width.round(), _lastSize.height.round());
}
paint(Canvas canvas, Size size) {
_lastCanvas = canvas;
_lastSize = size;
for (var point in this.allPoints) {
var paint = new Paint()..color = colorFromColorString(opts.penColor);
paint.strokeWidth = 5.0;
var path = new Path();
var offset = new Offset(point.point.x, point.point.y);
path.moveTo(point.point.x, point.point.y);
var pointSize = point.size;
if (pointSize == null || pointSize.isNaN) {
pointSize = opts.dotSize;
}
canvas.drawCircle(offset, pointSize, paint);
paint.style = PaintingStyle.stroke;
canvas.drawPath(path, paint);
}
}
bool shouldRepaint(SignaturePadPainter oldDelegate) {
return true;
}
}
Currently currently getPng() returns a dart:ui Image object, but I can't tell how to get the bytes from the image data (if this is even possible)
Here's the solution I came up with, now that toByteData() was added to the SDK:
var picture = recorder.endRecording();
var image =
picture.toImage(lastSize.width.round(), lastSize.height.round());
ByteData data = await image.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
This solution is working and has now been published to pub as part of the signature_pad_flutter package: https://github.com/apptreesoftware/signature-pad-dart/blob/master/signature_pad_flutter/lib/src/painter.dart#L17

Cache Images and load on scroll in UICollectionView with SDWebImageDownloader Xamarin

I have a UICollectionView with Cells with images which are downloaded from url along with headers. I do it something like below :-
internal void UpdateCell(ProfileValues mdata)
{
var mUrl = "someurl";
var manager = SDWebImageManager.SharedManager;
manager.ImageCache.MaxCacheAge = 86400;
SDWebImageDownloader mDownloader = manager.ImageDownloader;
var authToken = "SomeToken"";
mDownloader.SetHttpHeaderValue(authToken, "Authorization");
mDownloader.SetHttpHeaderValue("application/json; odata=verbose", "Accept");
mDownloader.SetHttpHeaderValue("f", "X-FORMS_BASED_AUTH_ACCEPTED");
try
{
mDownloader.DownloadImage(
url: new NSUrl(mUrl),
options: SDWebImageDownloaderOptions.ProgressiveDownload,
progressBlock: (receivedSize, expectedSize) =>
{
// Track progress...
},
completedBlock: (image, data, error, finished) =>
{
if (image != null && finished)
{
InvokeOnMainThread(() =>
{
this.imgProfilePic.Image = image;
});
}
if (error != null)
{
InvokeOnMainThread(() =>
{
this.imgProfilePic.Image = errorImage;
this.imgProfilePic.BackgroundColor = UIColor.FromRGB(52, 31, 71);
//this.imgProfilePic.Layer.CornerRadius = this.imgProfilePic.Frame.Size.Width / 2;
this.imgProfilePic.ClipsToBounds = true;
this.imgProfilePic.Layer.BorderWidth = 3.0f;
this.imgProfilePic.Layer.BorderColor = UIColor.White.CGColor;
});
}
}
);
}
catch (Exception ex)
{
}
}
But on every scroll the cells are reloaded and the images are downloaded everytime. How can I cache the images and load the images from the cache on scroll? Any help is appreciated.
Use FFImageLoading package & use the class cachedImage place of Image
var cachedImage = new CachedImage() {
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
WidthRequest = 300,
HeightRequest = 300,
CacheDuration = TimeSpan.FromDays(30),
DownsampleToViewSize = true,
RetryCount = 0,
RetryDelay = 250,
TransparencyEnabled = false,
Source = "http://loremflickr.com/600/600/nature?filename=simple.jpg",
CacheKeyFactory = new CustomCacheKeyFactory(),
};

for embedded PDFs, can PDFJS support both scrolling and jump to a page number at the same time?

This seems like it should be very standard behavior.
I can display a scrollable PDF with:
var container = document.getElementById('viewerContainer');
var pdfViewer = new PDFJS.PDFViewer({
container: container,
});
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
pdfViewer.setDocument(pdfDocument);
});
and I can display the PDF page by page with something like:
PDFJS.getDocument(URL_ANNOTATED_PDF_EXAMPLE).then(function getPdfHelloWorld(pdf) {
pdf.getPage(pageNumber).then(function getPageHelloWorld(page) {
var scale = 1.5;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
But can't seem to find any reference in the API to both allow scrolling and jumping to a particular page, besides:
pdfViewer.currentPageNumber = 3;
which doesn't work...
So I found a way to make this work (mixed with a little Angular code, "$scope.$watch...") I now have other problems with font decoding. But here is a solution that might help someone else.
var me = this;
PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK;
var container = document.getElementById('capso-court-document__container');
function renderPDF(url, container) {
function renderPage(page) {
var SCALE = 1;
var pdfPageView = new PDFJS.PDFPageView({
container: container,
id: page.pageIndex + 1,
scale: SCALE,
defaultViewport: page.getViewport(SCALE),
textLayerFactory: new PDFJS.DefaultTextLayerFactory(),
annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory()
});
pdfPageView.setPdfPage(page);
return pdfPageView.draw();
}
function renderPages(pdfDoc) {
var pageLoadPromises = [];
for (var num = 1; num <= pdfDoc.numPages; num++) {
pageLoadPromises.push(pdfDoc.getPage(num).then(renderPage));
}
return $q.all(pageLoadPromises);
}
PDFJS.disableWorker = true;
return PDFJS.getDocument(url)
.then(renderPages);
}
$scope.$watch(function() {
return {
filingUrl: me.filingUrl,
whenPageSelected: me.whenPageSelected,
};
}, function(newVal, oldVal) {
if (newVal.filingUrl) {
//newVal.filingUrl = URL_EXAMPLE_PDF_ANNOTATED;
//newVal.filingUrl = URL_EXAMPLE_PDF_ANNOTATED_2;
//newVal.filingUrl = URL_EXAMPLE_PDF_MULTI_PAGE;
if (newVal.filingUrl !== oldVal.filingUrl &&
newVal.whenPageSelected &&
newVal.whenPageSelected.page) {
scrollToPage(newVal.whenPageSelected.page);
}
//HACK - create new container for each newly displayed PDF
container.innerHTML = '';
var newContainerForNewPdfSelection = document.createElement('div');
container.appendChild(newContainerForNewPdfSelection);
renderPDF(newVal.filingUrl, newContainerForNewPdfSelection).then(function() {
if (newVal.whenPageSelected &&
newVal.whenPageSelected.page) {
scrollToPage(newVal.whenPageSelected.page);
}
});
}
}, true);
function scrollToPage(pageNumber) {
var pageContainer = document.getElementById('pageContainer' + pageNumber);
if (pageContainer) {
container.scrollTop = pageContainer.offsetTop;
} else {
console.warn('pdf pageContainer doesn\'t exist for index', pageNumber);
}
}

Setting the z-index of loader class

I'm working in Flash AS3, AIR 3.2 for iOS SDK. I'm loading in an image, then applying a shape and textfield over this. But it seems that z-index goes weird with the loader class. At the moment, when this is run, the text and shape is applied first, and the image then gets applied on top of these even though the methods are in a different order. How do I set the shape and text to be above an image that's loaded in from the loader class?
The methods in the main method:
displayImage();
overlayBox();
textAnimation();
These are the methods:
public function displayImage():void {
var imageurl:String = "image.jpg";
myLoader = new Loader();
var fileRequest:URLRequest = new URLRequest(imageurl);
myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoaderProgress);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
myLoader.load(fileRequest);
}
public function onLoaderProgress(e:ProgressEvent) {
trace(e.bytesLoaded, e.bytesTotal); // this is where progress will be monitored
}
public function onLoaderComplete(e:Event) {
image = new Bitmap(e.target.content.bitmapData);
var imageWidth:Number = image.width;
var imageHeight:Number = image.height;
var resizeWidthVar:Number;
var resizeHeightVar:Number;
trace("Image width: " + image.width);
trace("Image height: " + image.height);
if(imageWidth >= imageHeight) {
resizeHeightVar = imageHeight/displayRes;
trace("resizeHeightVar = " + resizeHeightVar);
imageWidth = imageWidth/resizeHeightVar;
imageHeight = imageHeight/resizeHeightVar;
}
else {
resizeWidthVar = imageWidth/displayRes;
trace("resizeWidthVar = " + resizeWidthVar);
imageWidth = imageWidth/resizeWidthVar;
imageHeight = imageHeight/resizeWidthVar;
}
image.width = imageWidth;
image.height = imageHeight;
trace("Image width: " + image.width);
trace("Image height: " + image.height);
image.x = xScreenPos;
image.y = yScreenPos;
addChild(image); // the image is now loaded, so let's add it to the display tree!
}
public function overlayBox():void {
var overlaySquare:Sprite = new Sprite();
addChild(overlaySquare);
overlaySquare.graphics.beginFill(0x00000, 0.7);
overlaySquare.graphics.drawRect(0, 0, displayRes, displayRes);
overlaySquare.graphics.endFill();
overlaySquare.x = xScreenPos;
overlaySquare.y = yScreenPos;
}
public function textAnimation():void {
//set text format
textFormat.font = "Helvetica Neue Light";
textFormat.size = 12;
textFormat.bold = false;
textFormat.color = 0x000000;
// pass text format
textOne.defaultTextFormat = textFormat;
textOne.text = "Blah blah blah blah";
textOne.autoSize = TextFieldAutoSize.LEFT;
textOne.x = xScreenPos;
textOne.y = yScreenPos;
//add to stage
addChild(textOne);
}
One of the solutions is to replace addChild(image); with the addChildAt(image, 0); another one is to add loader addChild(loader); and don't add image in the complete handler.

AS2 Print External image

I have this script where I can print the movie that i indicated in the code.
function print_page()
{
var my_pj = new PrintJob();
var myResult = my_pj.start();
if (myResult)
{
myResult = my_pj.addPage("img_mc", null, {printAsBitmap:true}, 1);
my_pj.send();
delete my_pj;
trace("ok");
}
}
I need to know, how to print some image that is outside the flahs... clicking in the MC.... but i need in AS2...
ty for help!
This is the only way i sucess print external image with PrintJob() and AS2
#include "mc_tween2.as"
_root.myholder.loadMovie("teste_labirinto.jpg");
_root.myholder._x = 0; //i set the x and y position of image out of the screen area!
_root.myholder._y = 990; //
function print_page()
{
var my_pj = new PrintJob();
var myResult = my_pj.start();
if (myResult)
{
my_pj.orientation = portrait;
myResult = my_pj.addPage("myholder", {xMin:0, xMax:600, yMin:0, yMax:800}, {printAsBitmap:true}, 1);
my_pj.my_pj.send();
delete my_pj;
trace("ok");
}
}
btn.onRelease = function()
{
print_page();
};

Resources