Make picture from base64 on client-side - dart

How to make a picture from a base64-string to send it to server by using HttpRequest.request?
For example, I have the following base64-string:
'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
Instead of sending it I would like to post a jpeg to server? Is it possible?

Convert Base64 to bytes
How to native convert string -> base64 and base64 -> string
Upload binary as image
Dart how to upload image
EDIT
(this is the server part, I have to look for the client part)
Client code:
var request = new HttpRequest()
..open("POST", 'http://yourdomain.com/yourservice')
..overrideMimeType("image/your-imagetype") // might be that this doesn't work than use the next line
..setRequestHeader("Content-Type", "image/your-imagetype")
..onProgress.listen((e) => ...);
request
..onReadyStateChange.listen((e) => ...)
..onLoad.listen((e) => ...)
..send(yourBinaryDataAsUint8List);
Convert to image:
I think you need to create a dataURL like show here How to upload a file in Dart?
and then use the created dataUrl as src in code like shown here How to load an image in Dart
see also Base64 png data to html5 canvas as #DanFromGermany mentioned in his comment on the question.
It may be necessary to convert List to Uint8List in between.
Please add a comment if you need more information.

I like decoding on server-side, but anyways.
Basically you just split a text you got from canvas.toDataUrl(), convert the Base64 text to binary data, then send it to server. Use "CryptoUtils" in "crypto" library to treat Base64. I haven't tested with any proper http server, but this code should work.
// Draw an on-memory image.
final CanvasElement canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
final CanvasRenderingContext2D context = canvas.getContext('2d');
final CanvasGradient gradient = context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, "#1e4877");
gradient.addColorStop(0.5, "#4584b4");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(10, 10);
context.lineTo(240, 240);
context.lineWidth = 10;
context.strokeStyle = '#ff0000';
context.stroke();
// Convert the image to data url
final String dataUrl = canvas.toDataUrl('image/jpeg');
final String base64Text = dataUrl.split(',')[1];
final Uint8ClampedList base64Data = new Uint8ClampedList.fromList(
CryptoUtils.base64StringToBytes(base64Text));
// Now send the base64 encoded data to the server.
final HttpRequest request = new HttpRequest();
request
..open("POST", 'http://yourdomain.com/postservice')
..onReadyStateChange.listen((_) {
if (request.readyState == HttpRequest.DONE &&
(request.status == 200 || request.status == 0)) {
// data saved OK.
print("onReadyStateChange: " + request.responseText); // output the response from the server
}
})
..onError.listen((_) {
print("onError: " + _.toString());
})
..send(base64Data);
I posted a complete snippet here. https://gist.github.com/hyamamoto/9391477

I found the Blob conversion part not to be working (anymore?).
The code from here does work:
Blob createImageBlob(String dataUri) {
String byteString = window.atob(dataUri.split(',')[1]);
String mimeString = dataUri.split(',')[0].split(':')[1].split(';')[0];
Uint8List arrayBuffer = new Uint8List(byteString.length);
Uint8List dataArray = new Uint8List.view(arrayBuffer.buffer);
for (var i = 0; i < byteString.length; i++) {
dataArray[i] = byteString.codeUnitAt(i);
}
Blob blob = new Blob([arrayBuffer], mimeString);
return blob;
}

Related

How to convert SvelteKit fetch response to a buffer?

I have a simple node script to fetch tif image, use sharp to convert the image to jpeg and generate data:image/jpeg;base64 src for browser. The reason is to enable tiff image in browsers that do not support tif/tiff images.
In node this works great.
import sharp from "sharp";
import fetch from "node-fetch";
let link =
"https://people.math.sc.edu/Burkardt/data/tif/at3_1m4_01.tif";
// fetch tif image and save it as a buffer
async function fetchTifBuffer(link) {
const tifImg = await fetch(link);
const buffer = await tifImg.buffer();
return buffer;
}
// convert to png image save to buffer and save as base64
async function tifToPngToBase64(link) {
let inputImgBuffer = await fetchTifBuffer(link);
const buff = await sharp(inputImgBuffer).toFormat("jpeg").toBuffer();
let base64data = buff.toString("base64");
let imgsrc = "data:image/jpeg;base64," + base64data.toString("base64");
console.log(imgsrc);
// use in browser <img src="data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAY ...==" alt="image" />
}
tifToPngToBase64(link);
I would like to implement this in SvelteKit. But I have no idea how to get buffer from SvelteKit fetch response. Any ideas?
Ok, so I figured it out by myself. SvelteKit fetch response has an arrayBuffer, so all that is needed is to convert the arraybuffer to the buffer.
This is the relevant SvelteKit endpoint:
// img.js
import sharp from "sharp";
export const get = async () => {
const res = await fetch(
"https://people.math.sc.edu/Burkardt/data/tif/at3_1m4_01.tif"
);
const abuffer = await res.arrayBuffer();
const buffer = Buffer.from(new Uint8Array(abuffer));
const buff = await sharp(buffer).toFormat("jpeg").toBuffer();
let base64data = buff.toString("base64");
let src = `data:image/jpeg;base64,${base64data.toString("base64")}`;
let img = `<img style='display:block; width:100px;height:100px;' id='base64image'
src='${src}' />`;
return {
body: {
img,
},
};
};
and this is the SvelteKit component which uses the endpont:
// img.svelte
<script>
export let img;
</script>
{#html img}

Generate torrent links from server-side

I don't know a lot about torrents, at least not enough to understand how certain websites can offer both a normal download link and a torrent link to download a file uploaded by a user.
Is generating a torrent link something common and simple to achieve. Would I need a server installation?
I've made an ugly C# implementation from a Java source, and to make sure some of my encoded variables were correct, I used NBEncode from Lars Warholm.
// There are 'args' because I'm using it from command-line. (arg0 is an option not used here)
// Source file
args[1] = Directory.GetCurrentDirectory() + args[1];
// Name to give to the torrent file
args[2] = Directory.GetCurrentDirectory() + args[2];
var inFileStream = new FileStream(args[1], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var filename = args[2];
//BEncoding with NBEencode
var transform = new BObjectTransform();
MemoryStream s = new MemoryStream();
OSS.NBEncode.Entities.BDictionary bod = new OSS.NBEncode.Entities.BDictionary();
OSS.NBEncode.Entities.BDictionary meta = new OSS.NBEncode.Entities.BDictionary();
// Preparing the first part of the file by creating BEncoded objects
string announceURL = "https://www.mysite.com/announce";
int pieceLength = 512 * 1024;
bod.Value.Add(new BByteString("name"), new OSS.NBEncode.Entities.BByteString(filename));
bod.Value.Add(new BByteString("length"), new OSS.NBEncode.Entities.BInteger(inFileStream.Length));
bod.Value.Add(new BByteString("piece length"), new OSS.NBEncode.Entities.BInteger(pieceLength));
bod.Value.Add(new BByteString("pieces"), new BByteString(""));
meta.Value.Add(new BByteString("announce"), new BByteString(announceURL));
meta.Value.Add(new BByteString("info"), bod);
byte[] pieces = hashPieces(args[1], pieceLength);
transform.EncodeObject(meta, s);
s.Close();
// Notice that we finish with a dictionary entry of "pieces" with an empty string.
byte[] trs = s.ToArray();
s.Close();
inFileStream.Close();
// I don't know how to write array of bytes using NBEncode library, so let's continue manually
// All data has been written a MemoryStreamp, except the byte array with the hash info about each parts of the file
Stream st = new FileStream(filename + ".torrent", FileMode.Create);
BinaryWriter bw = new BinaryWriter(st);
// Let's write these Bencoded variables to the torrent file:
// The -4 is there to skip the current end of the file created by NBEncode
for (int i = 0; i < trs.Length - 4; i++)
{
bw.BaseStream.WriteByte(trs[i]);
}
// We'll add the length of the pieces SHA1 hashes:
var bt = stringToBytes(pieces.Length.ToString() + ":");
// Then we'll close the Bencoded dictionary with 'ee'
var bu = stringToBytes("ee");
// Let's append this to the end of the file.
foreach (byte b in bt)
{
bw.BaseStream.WriteByte(b);
}
foreach (byte b in pieces)
{
bw.BaseStream.WriteByte(b);
}
foreach (byte b in bu)
{
bw.BaseStream.WriteByte(b);
}
bw.Close();
st.Close();
// That's it.
}
Functions used:
private static byte[] stringToBytes(String str)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] bytes = encoding.GetBytes(str);
return bytes;
}
private static byte[] hashPieces(string file, int pieceLength)
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
StreamReader inn = new StreamReader(file);
MemoryStream pieces = new MemoryStream();
byte[] bytes = new byte[pieceLength];
byte[] digest = new byte[20];
int pieceByteCount = 0, readCount = inn.BaseStream.Read(bytes, 0, pieceLength);
while (readCount != 0)
{
pieceByteCount += readCount;
digest = sha1.ComputeHash(bytes, 0, readCount);
if (pieceByteCount == pieceLength)
{
pieceByteCount = 0;
foreach (byte b in digest)
{
pieces.WriteByte(b);
}
}
readCount = inn.BaseStream.Read(bytes, 0, pieceLength - pieceByteCount);
}
inn.Close();
if (pieceByteCount > 0)
foreach (byte b in digest)
{
pieces.WriteByte(b);
}
return pieces.ToArray();
}
It depends on how you're trying to create it. If you run a website, and want to generate torrent files from uploaded files, then you'll obviously need server-side code.
Generating a torrent file involves: adding the files you want to the torrent, and adding tracker info. Some popular trackers are:
http://open.tracker.thepiratebay.org/announce
http://www.torrent-downloads.to:2710/announce
To create the .torrent file, you'll have to read the about the format of the file. A piece of Java that generates .torrent files is given at https://stackoverflow.com/a/2033298/384155

Failed to upload a local image file onto google doc with format converted

For public link it works fine, but in my case I need upload a image file from local disk. I converted the image into base64 format, and write the html file into local disk as well, that html file can be opened in browser with image showing, but the document in google doc just an empty file, even I drag that html file into google docs the image still not there. My code is below:
DocsService client = new DocsService("testappv3");
client.setUserCredentials("username", "password");
File file = new File("c:/test.bmp");
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
out.flush();
String base64 = Base64.encode(out.toByteArray());
String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
String html = "<html><body><img src=\"data:" + mimeType + ";base64," + base64 + "\"/></body></html>";
URL destFolderUrl = new URL("https://docs.google.com/feeds/default/private/full/<FOLDER_ID>/contents");
DocumentEntry newDocument = new DocumentEntry();
newDocument.setTitle(new PlainTextConstruct("test"));
newDocument.setMediaSource(new MediaByteArraySource(html.getBytes(), "text/html"));
newDocument = client.insert(destFolderUrl, newDocument);
Look my experience level is only a few years so I could well be wrong but .... My understanding is that you can no longer use
client.insert(destFolderUrl, newDocument);// but now must use ResumableGDataFileUploader
new ResumableGDataFileUploader.Builder(client, new URL(uploadLink), mediaFile, null )
hopefully someone with more knowledge will confirm or deny

Extracting jfif image from 2d barcode

I have data read from 2d bar code pdf417. It contains an embedded image in the format of (jfif), The image is not at the beginning of the decoded data it has some data fields and the image is somewhere after, the data fields does not seam to have fixed lengths. How can I extract the Image from the decoded data. I used ClearImage Library to decode the barcode and I have it as text and Hex.
Please help. Thank you in advance
I was able to extract the image thanks to many experts in StackOverflow, I have being reviewing their posts. The following code explains how to extract the image from a mixed binary file, the code is not so beautiful but it can do the job. It searches for (JFIF) image header and extracts it into an image file.
public static void ExtractImage(string fname)
{
try
{
FileStream fs = new FileStream(fname, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
//read the first binary
char[] soi="Empty".ToCharArray();
br.BaseStream.Position = 0;
long imgpos = 0;
ushort r = 0;
while ((r = br.ReadUInt16())> 0)
{
Console.WriteLine(r);
if (r == 0xd8ff)
{
Console.WriteLine("Detcted----->");
imgpos = br.BaseStream.Position;
break;
//UInt16 jfif = br.ReadUInt16(); // JFIF marker
//Console.WriteLine("jfif " + jfif);
//if (jfif == 0xe0ff || jfif == 57855)
// Console.WriteLine(" also Detected--->");
}
}
//now copy to stream
FileStream str = new FileStream("bcimage.jpg", FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(str);
br.BaseStream.Position = imgpos-2;
int l = (int)(fs.Length - imgpos - 2);
bw.Write(br.ReadBytes(l));
fs.Close();
br.Close();
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
}

How-to: Byte array of an image to string, send back through HTTP request, then back to byte[] image?

I have a byte array of an image on the server.
Using MVC as a pseudo-REST web service interface.
I'm in need of sending this image back through the HTTP request to the MVC client to render.
My first attempt was using UFT8Encoding to encode it to a string, send that cross then decode it using UTF8Encoding on the client.
However, when I do this, the result on the client is null. I assume due to the format of the string that I'm trying to send back.
This is what I'm doing now to no avail:
byte[] image = GetBarcodeImage(barcode);
if (image != null)
{
UTF8Encoding enc = new UTF8Encoding();
result = enc.GetString(image);
}
This is on the client side:
UTF8Encoding encoding= new UTF8Encoding();
byte[] image = encoding.GetBytes(result);
string imageBase64 = Convert.ToBase64String(image);
string imgsrc = string.Format("data:image/gif;base64,{0}", imageBase64);
Is there any reason you don't return it as an image from your controller?
var image = GetByteArrayImage();
var stream = new MemoryStream(image);
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Expires = 14400;
return File(stream, "image/jpg");
Thin in your client you can just use WebRequest to download the file like any other file and not have to do any other magic.

Resources