Im currently getting a base64 image data url from a canvas something like this (not the dataurl im getting just to show how the string looks like)
data:image/png;base64,iVkhdfjdAjdfirtn=
I need to decode that image to check the width and the height of the image
dataurl := strings.Replace(req.PostFormValue("dataurl"), "data:image/png;base64,", "", 1)
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(dataurl))
c, _, err := image.DecodeConfig(reader)
if err != nil {
log.Fatal(err)
}
log.Println(c.Width)
But Im getting an error while trying to decode the config
Unknown image format
So yeah the way Im making the dataurl must be wrong but cant figure what to do. I also tried passing the full dataurl (with data:image...) still no success
What you have is a Data URI scheme, info on how to decode it and more on this is in this question and answer:
Illegal base64 data at input byte 4 when using base64.StdEncoding.DecodeString(str)
But note that image.Decodeconfig() will only decode image formats that are registered prior to calling this function, so you need the image format handlers to be registered in advance. This can be done with imports like
import _ "image/png"
More on this is in the package doc of image. Or if you know the exact format (e.g. in your example it's PNG), you can directly use png.DecodeConfig().
So it doesn't work for you because your actual encoded image is of PNG format, but you didn't register the the PNG format handler and so image.DecodeConfig() won't use the PNG handler (and so it will not be able to decode it => "Unknown image format").
Also note that replacing the prefix that is not part of the Base64 encoded image is a poor solution to get rid of it. Instead simply slice the input string:
input := "data:image/png;base64,iVkhdfjdAjdfirtn="
b64data := input[strings.IndexByte(input, ',')+1:]
Slicing a string will not even copy the string in memory, it will just create a new (two-word) string header.
Related
I want to convert an Embedded image to base 64 string. The image is in PCL solution so let me know how to convert an image into base64. As I tried lots of ways but I am not getting the file path properly. So please help me with this.
//file to base64 string
byte[] b = System.IO.File.ReadAllBytes(FileName);
String s = Convert.ToBase64String(b);
//base64 string to file
byte[] data = Convert.FromBase64String(s);
System.IO.File.WriteAllBytes(FileName2, data);
Since it is an embedded resource getting the path for the image is a problem to convert it into a stream, you can take the following steps to get the path of your embedded image:
string imagePath = "NameOfProject.Assets.applicationIcon.png";
Note: This is the sample path in your case you will give your path, Where the name of the project is the name of the project, Assets is the folder in which I have the image and application icon is the image. (I hope you understood what I am doing here)
After that get the Assembly details something like this:
Assembly assembly = typeof(NameOfClass).GetTypeInfo().Assembly;
Then inside a using statement convert your image into a stream, Something like this
string result;
using (Stream stream = assembly.GetManifestResourceStream(imagePath))
{
long length = stream.Length;
byte[] buffer = new byte[length];
stream.Read(buffer, 0, (int)length);
result = Convert.ToBase64String(data);
}
Revert in case of queries.
I'm trying to download a PNG image in Apps Script, convert it to JPEG, and generate a data URI for this new JPEG.
function test() {
var blob = UrlFetchApp.fetch('https://what-if.xkcd.com/imgs/a/156/setup.png').getBlob();
var jpeg = blob.getAs("image/jpeg");
var uri = 'data:image/jpeg;base64,' + Utilities.base64Encode(jpeg.getBytes());
Logger.log(uri);
}
When I run this, I get:
The image you are trying to use is invalid or corrupt.
Even something like:
function test() {
var bytes = UrlFetchApp.fetch('https://what-if.xkcd.com/imgs/a/156/setup.png').getBlob().getBytes();
var jpeg = Utilities.newBlob(bytes, MimeType.PNG).getAs(MimeType.JPEG);
DriveApp.createFile(jpeg);
}
doesn't work.
Your code is correct. This may be a bug, but it's specific to the file you are using, so may as well be a bug in the file (i.e., the file could indeed be corrupted somehow). Or maybe it uses some features of PNG format that Google doesn't handle. Replacing the URL by another one, e.g.,
var blob = UrlFetchApp.fetch('https://cdn.sstatic.net/Sites/mathematica/img/logo#2.png').getBlob();
both functions work as expected.
Is it possible to convert an NSattributedString with attachments (RTFD not RTF) to ASCII, edit the stream, and convert it back? So far I am able to convert an RTFD to a String stream. But turning it back into an NSData object does not work. Here's the code I'm using in a playground.
import Cocoa
func stream(attr: NSAttributedString) -> String? {
if let d = attr.rtfd(from: NSMakeRange(0, attr.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType]) {
if let str = String(data: d, encoding: .ascii) { return str }
else {
print("Unable to produce RTFD string")
return nil
}
}
print("Unable to produce RTFD data stream")
return nil
}
if let im = NSImage(named: "image.png") {
let a = NSTextAttachment()
a.image = im
let s = NSAttributedString(attachment: a)
if let str = stream(attr: s) {
print("\(str)\n") //prints a string, which contains RTF code combined with NSTextAttachment string representation
if let data = str.data(using: .ascii) { //this is where things stop working
if let newRTF = NSAttributedString(rtfd: data as Data, documentAttributes: nil) {
print(newRTF)
}
else { print("rtfd was not created") }
}
else { print("could not make data") }
}
}
What am I missing? Or is my entire concept wrong here? I am doing this to get around a limitation of the way OS X handles images attached in RTF documents.
Edit:
The limitation I am trying to address is to set the size of an image in an RTF stream. The text handling system requires that we use NSTextAttachment. Whenever an image is pasted from that, it automatically sizes the image to whatever the pixel height and width are. Unfortunately there is no way to control this property. I have tried here and also using all the techniques here.
As far as the ASCII stream, I'm not trying to edit the image attachment itself. When the stream is printed, the actual RTF code is visible and editable. This works and would be a good workaround for this limitation. All I need is to edit the RTF code and change the \width and \height properties that Apple uses.
After your edit I can see what you are trying to do, interesting idea, but it won't work - at least not easily.
Take a look at the value of d, it is not an ASCII string stored as a value of type Data (or NSData). It is a serialised representation of multiple items; the RTF stream (text), the image data (binary). If you convert this to an ASCII string and back again it is not going to work, you can't represent arbitrary binary data as ASCII unless you encode it (e.g. something like base 64 encoding).
Now you could attempt what you are trying a slightly different way, skip the conversion to ASCII and edit the Data value directly. That is certainly possible, but as you are editing a format you don't know (the serialised representation) you would have to be careful... And even if you succeed in editing the representation there is no guarantee that converting back to an NSAttributedString with an NSTextAttachment will preserve your edits.
I suggest you tackle this another way. You have an NSAttributedString and you don't like the RTF produced after you write this to a file. So edit the RTF after it is written, e.g. open up the RTFD package, open the contained RTF file (TXT.rtf), edit it, write it back.
HTH
I need get an image from a URL and display in a view. How can do this in Cincom Smalltalk?
For example, I have this image URL:
http://news.bbcimg.co.uk/media/images/64001000/jpg/_64001280_63976026.jpg
And I wish display the image. I try:
|req content reader|
req := HttpRequest
get:'http://news.bbcimg.co.uk/media/images/64001000/jpg/_64001280_63976026.jpg' asURI.
content:=req execute.
reader := JPEGImageReader new.
reader from: content byteSource.
But it doesn't work. Cincom Smalltalk says:
Image incomplete or partially corrupted JFIF marker expected.
when I execute: JPEGImageReader>>parseFirstMarker.
The "byteSource" method is returning a stream that's already positioned to the end of file. When the JPEG reader starts to read, I hits the end and aborts.
You really shouldn't be using the byteSource method. If the contents of the URI are compressed, you won't get them properly decompressed. You should fetch the byteContents and open a readStream on that result as follows:
|req content reader image |
req := HttpRequest
get:'http://news.bbcimg.co.uk/media/images/64001000/jpg/_64001280_63976026.jpg' asURI.
content:=req execute.
reader := JPEGImageReader new.
image := (reader from: content byteContents readStream) image
I'm getting a CVImageBufferRef from my AVCaptureSession, and I'd like to take that image buffer and upload it over the network. To save space and time, I would like to do this without rendering the image into a CIImage and NSBitmapImage, which is the solution I've seen everywhere (like here: How can I obtain raw data from a CVImageBuffer object).
This is because my impression is that the CVImageBuffer might be compressed, which is awesome for me, and if I render it, I have to uncompress it into a full bitmap and then upload the whole bitmap. I would like to take the compressed data (realizing that a single compressed frame might be unrenderable later by itself) just as it sits within the CVImageBuffer. I think this means I want the CVImageBuffer's base data pointer and its length, but it doesn't appear there's a way to get that within the API. Anybody have any ideas?
CVImageBuffer itself is an abstract type. Your image should be an instance of either CVPixelBuffer, CVOpenGLBuffer, or CVOpenGLTexture. The documentation for those types lists the functions you can use for accessing the data.
To tell which type you have use the GetTypeID methods:
CVImageBufferRef image = …;
CFTypeID imageType = CFGetTypeID(image);
if (imageType == CVPixelBufferGetTypeID()) {
// Pixel Data
}
else if (imageType == CVOpenGLBufferGetTypeID()) {
// OpenGL pbuffer
}
else if (imageType == CVOpenGLTextureGetTypeID()) {
// OpenGL Texture
}