How to convert DynamicImage to Base64? - image-processing

I can convert a Base64 string to a DynamicImage using the image and base64 crates but I can not convert the image back to a Base64 string.
What I am doing wrong here? How to achieve this?
extern crate base64;
extern crate image;
fn main() {
/*
Base64 to image
let img_buffer = base64::decode("qwerty...").unwrap();
let mut base_img = image::load_from_memory(img_buffer.as_slice()).unwrap();
*/
let mut base_img = image::open("player.png").unwrap();
base_img.invert();
// base_img.save("player1.png").unwrap();
// image to Base64
let res_base64 = base64::encode(base_img.raw_pixels().as_slice());
println!("{}", res_base64)
}
Base64 value of original image
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAgAElEQVR42uydd5hlRZn/v1Un3dzdt/P0pJ6enANxGKISFEQkg4ur6667uquuCiKCIJKUpAj7U3cN66orWVERVxBmmDxMYHLOM90znfvGk6rq98e9ICoo0Kf73u5+P8+DjPBwZrpO1Xm...
Base64 value of Gimp inverted image
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH4wgMCCwxQF4N2QAAIABJREFUeNrsvXmc3FWZ7...
The response I am getting not the proper Base64 value:
////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///...

The Base64 values of the original and Gimp images represent PNG-encoded images. The response you're getting represents raw pixel data. You will need to convert the data to PNG before encoding as Base64. This should do it:
let mut buf = vec![[]];
base_img.write_to(&mut buf, image::ImageOutputFormat::PNG);
let res_base64 = base64::encode(&buf);

My 2022 solution is:
#Cargo.toml
[dependencies]
base64 = "0.13"
image = "0.24"
use image::{DynamicImage, ImageOutputFormat};
use std::io::Cursor;
fn image_to_base64(img: &DynamicImage) -> String {
let mut image_data: Vec<u8> = Vec::new();
img.write_to(&mut Cursor::new(&mut image_data), ImageOutputFormat::Png)
.unwrap();
let res_base64 = base64::encode(image_data);
format!("data:image/png;base64,{}", res_base64)
}
let img = image::load_from_memory(&data.clone()).unwrap();
println!("{}", image_to_base64(&img));
You can use this string for html tag <img src="..." />.

Related

How to use Rust OpenCV imdecode

I'd like decode a PNG image into an OpenCV Mat object using imdecode. I'm working on a function like
fn handle_frame(buf: &[u8]) -> Result<(), opencv::Error> {
original_image: Mat = imgcodecs::imdecode(buf, imgcodecs::IMREAD_COLOR)?;
let width = original_image.cols()?;
let height = original_image.rows()?;
println!("Success! Dimensions are {}x{}", width, height);
Ok(())
}
But I cannot pass by byte buffer to imdecode because I'd first need to convert it to something that has the ToInputArray trait. How to do this?
I found out that when I change the type of the input buffer to Vec<u8> I can do this:
let original_image: Mat = imgcodecs::imdecode(&VectorOfuchar :: from_iter(buf), imgcodecs::IMREAD_COLOR)?;
Here is a mostly complete example:
let filename = "somepicture.png";
let mut reader: Box<dyn BufRead> = Box::new(BufReader::new(File::open(filename)?));
let mut buffer : Vec<u8> = Vec::new();
let _read_count = reader.read_to_end(&mut buffer)?;
let result = cv::imgcodecs::imdecode(&cv::types::VectorOfu8::from_iter(buffer), cv::imgcodecs::IMREAD_COLOR)?;
cv::highgui::imshow(&filename, &result)?;
let _key = cv::highgui::wait_key(0)?;

I received a response from the sever I wanted to decode it before I use it further

I have a string received from the server and I was trying to decode the string with padding but it is throwing nil as result. I tried codes that are available in stack overflow but of no use. Help will be highly appreciated.
I tried with base64 encoded with ignore unknown characters option and padding, still it throws nil.
let pem = "MIICyjCCAjOgAwIBAgIDBJPhMA0GCSqGSIb3DQEBBQUAMHsxEjAQBgNVBAMTCVJvb3RjZXJ0MTESMBAGA1UECRMJYmVsbGFuZHVyMQswCQYDVQQIEwJrYTEPMA0GA1UEERMGODg4ODg4MQwwCgYDVQQLEwNlc3MxGDAWBgNVBAoTD2VtdWRocmEgbGltaXRlZDELMAkGA1UEBhMCaW4wHhcNMTkwNzExMTAzNzM4WhcNMjgxMjI2MTAzNzM4WjB0MREwDwYDVQQDEwhBdmFkaGVzaDEMMAoGA1UECRMDYnRtMQswCQYDVQQIEwJrYTEPMA0GA1UEERMGODc4Nzg3MQwwCgYDVQQLEwNlc3MxGDAWBgNVBAoTD2VtdWRocmEgbGltaXRlZDELMAkGA1UEBhMCaW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMDAm7W3nc3hyyAhG8RBCSmlSDzcU/C39dPEFPq3N0JpSghMojnZg0jnfwXCvWqtPhlTYEdVLSXRehmQpS2v/FN8wkqZoVaKHNQE1UJnzPbyjfTlQA20nlCNVTNBQ70rWYzfuuFhliUBycGbYaIE/VGk354AEdXipLklCPf7PsgZAgMBAAGjYzBhMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUkdq9ZIGVtD0x6k6hO7PdFMidh/QwHQYDVR0OBBYEFDwUkx0+5e1xTcavaVBpvREel/hZMAsGA1UdDwQEAwIBzjANBgkqhkiG9w0BAQUFAAOBgQBIDy2MjWWsZC9G1k3DFYyP2/jsj/xzKyQh2e5YrnxIGtK5jBRKZe3JOuq1wxMzRfzd22lnSyKzf4dKMp2ADXJnNQrB/aafGs9nf+FXuIomquZHoNGrThfSyB/tre8T3dMWRiUdYy74XL2wvQb6tVHPQ/UEPSYOyf3XDSnzpgtjmw=="
let decodedData = NSData(base64Encoded: dataStr, options: .ignoreUnknownCharacters)
let length = dataStr.count
dataStr = dataStr.padding(toLength: length + (4 - length % 4) % 4, withPad: "=", startingAt: 0)`
It has to give some decoded data with which I can create a certificate because the response is in the format of .cert.
A certificate is not a string. You cannot create a string from the raw Data.
You can decode the base64 encoded string simply with
let decodedData = Data(base64Encoded: dataStr)
Notes:
Don't use NSData in Swift.
The ignoreUnknownCharacters is not needed.
The padding is wrong. It's only required when encoding the data and the base64 related API of String and Data adds the = characters automatically.
May be It will Help
For Image I am doing like this
I am converting UIImage To data and Converting That data to base64EncodedString
let imageData = UIimage.pngData()
//encode string
let imgBase64Str = imageData?.base64EncodedString(options: .lineLength64Characters) ?? ""
//decoding string to data
let decodedData = Data(base64Encoded: imgBase64Str, options: .ignoreUnknownCharacters)

String with Unicode (variable) [duplicate]

I have a problem I couldn't find a solution to.
I have a string variable holding the unicode "1f44d" and I want to convert it to a unicode character 👍.
Usually one would do something like this:
println("\u{1f44d}") // 👍
Here is what I mean:
let charAsString = "1f44d" // code in variable
println("\u{\(charAsString)}") // not working
I have tried several other ways but somehow the workings behind this magic stay hidden for me.
One should imagine the value of charAsString coming from an API call or from another object.
One possible solution (explanations "inline"):
let charAsString = "1f44d"
// Convert hex string to numeric value first:
var charCode : UInt32 = 0
let scanner = NSScanner(string: charAsString)
if scanner.scanHexInt(&charCode) {
// Create string from Unicode code point:
let str = String(UnicodeScalar(charCode))
println(str) // 👍
} else {
println("invalid input")
}
Slightly simpler with Swift 2:
let charAsString = "1f44d"
// Convert hex string to numeric value first:
if let charCode = UInt32(charAsString, radix: 16) {
// Create string from Unicode code point:
let str = String(UnicodeScalar(charCode))
print(str) // 👍
} else {
print("invalid input")
}
Note also that not all code points are valid Unicode scalars,
compare Validate Unicode code point in Swift.
Update for Swift 3:
public init?(_ v: UInt32)
is now a failable initializer of UnicodeScalar and checks if the
given numeric input is a valid Unicode scalar value:
let charAsString = "1f44d"
// Convert hex string to numeric value first:
if let charCode = UInt32(charAsString, radix: 16),
let unicode = UnicodeScalar(charCode) {
// Create string from Unicode code point:
let str = String(unicode)
print(str) // 👍
} else {
print("invalid input")
}
This can be done in two steps:
convert charAsString to Int code
convert code to unicode character
Second step can be done e.g. like this
var code = 0x1f44d
var scalar = UnicodeScalar(code)
var string = "\(scalar)"
As for first the step, see here how to convert String in hex representation to Int
As of Swift 2.0, every Int type has an initializer able to take String as an input. You can then easily generate an UnicodeScalar corresponding and print it afterwards. Without having to change your representation of chars as string ;).
UPDATED: Swift 3.0 changed UnicodeScalar initializer
print("\u{1f44d}") // 👍
let charAsString = "1f44d" // code in variable
let charAsInt = Int(charAsString, radix: 16)! // As indicated by #MartinR radix is required, default won't do it
let uScalar = UnicodeScalar(charAsInt)! // In Swift 3.0 this initializer is failible so you'll need either force unwrap or optionnal unwrapping
print("\(uScalar)")
You can use
let char = "-12"
print(char.unicodeScalars.map {$0.value }))
You'll get the values as:
[45, 49, 50]
Here are a couple ways to do it:
let string = "1f44d"
Solution 1:
"&#x\(string);".applyingTransform(.toXMLHex, reverse: true)
Solution 2:
"U+\(string)".applyingTransform(StringTransform("Hex/Unicode"), reverse: true)
I made this extension that works pretty well:
extension String {
var unicode: String? {
if let charCode = UInt32(self, radix: 16),
let unicode = UnicodeScalar(charCode) {
let str = String(unicode)
return str
}
return nil
}
}
How to test it:
if let test = "e9c8".unicode {
print(test)
}
//print:
You cannot use string interpolation in Swift as you try to use it. Therefore, the following code won't compile:
let charAsString = "1f44d"
print("\u{\(charAsString)}")
You will have to convert your string variable into an integer (using init(_:radix:) initializer) then create a Unicode scalar from this integer. The Swift 5 Playground sample code below shows how to proceed:
let validCodeString = "1f44d"
let validUnicodeScalarValue = Int(validCodeString, radix: 16)!
let validUnicodeScalar = Unicode.Scalar(validUnicodeScalarValue)!
print(validUnicodeScalar) // 👍

Proper way of Encoding image as base64String

Currently, I am trying to send image to backend to upload an image in my project. I have seen all possible answer on stack overflow and elsewhere but can not successfully send the data to backend . Even if I send,due to some problem(most probably due to white spaces as I feel), image decoded in backend side is not being in proper format.
Code to encode -
let imageData1 : NSData = UIImageJPEGRepresentation(slctdImage, 0.1)!
let base64StringNew1 = imageData1.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
Now the intresting part -
When I decode that using SWIFT code locally, I get the image and I am being able to display it in an image View. But same string when I convert in any online bse64 converter, I don't get the result .
code used for decoding -
let decodedData = NSData(base64EncodedString:base64StringNew1, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
So what might be my problem . Can any one please suggest the correct way to upload images to backend using base64String?
Try with this
func encodeImage(dataImage:UIImage) -> String{
let imageData = UIImagePNGRepresentation(dataImage)
return imageData!.base64EncodedStringWithOptions([])
}
Checked in http://codebeautify.org/base64-to-image-converter and works
Below code for image encoding.
let image: UIImage = imgProfilePic.image!
let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(0.3, 0.3))
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
image.drawInRect(CGRect(origin: CGPointZero, size: size))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
var imageData = UIImageJPEGRepresentation(scaledImage, 0.9)
var base64String = imageData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) // encode the image
var cd = CoreDataUser(pstrContext: "this")
var params = "strUsername=" + cd.getUsername()
params = params + "&strPassword=" + cd.getPassword()
params = params + "&blbProfilePic=" + base64String
PHP code where the base64 string is being decoded and displayed in the browser.
if ($rows) {
foreach ($rows as $row) {
$data = base64_decode($row["fblbProfilePic"]);
$image = imagecreatefromstring($data);
header('Content-Type: Image/jpeg');
imagejpeg($image);
//file_put_contents("test.jpg", $data);
//var_dump($data);
//echo base64_decode($row["fblbPicture"]);
/ /echo '<img src="data:image/jpg;base64,' . $row["fblbPicture"] . '" />';
}

Convert Hexadecimal String to Base64 in Swift

Is there a way to convert a hexadecimal string to base64 in Swift? For example, I would like to convert:
BA5E64C0DE
to:
ul5kwN4=
It's possible to convert a normal string to base64 by using:
let hex: String = "BA5E64C0DE"
let utf8str: NSData = hex.dataUsingEncoding(NSUTF8StringEncoding)!
let base64Encoded: NSString = utf8str.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
let base64: String = (base64Encoded as String)
But this would give a result of:
QkE1RTY0QzBERQ==
Because it's just treating the hex as a normal UTF-8 String, and not hexadecimal.
It's possible to convert it to base64 correctly by looping through every six hex characters and converting it to it's four respective base64 characters, but this would be highly inefficient, and is just plain stupid (there would need to be 17,830,160 if statements):
if(hex == "000000"){base64+="AAAA"}
else if(hex == "000001"){base64+="AAAB"}
else if(hex == "000002"){base64+="AAAC"}
else if(hex == "BA5E64"){base64+="ul5k"}
//...
It would be nice if there was something like this:
let hex: String = "BA5E64C0DE"
let data: NSData = hex.dataUsingEncoding(NSHexadecimalEncoding)!
let base64Encoded: NSString = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
let base64: String = (base64Encoded as String)
But sadly, there's no NSHexadecimalEncoding. Is there any efficient way to convert a hexadecimal string to it's base64 representation in Swift?
The base-64 string, "ul5kwN4=", translates to a binary NSData consisting of of five bytes BA, 5E, 64, C0, and DE.
Now, if you really had a string with the hexadecimal representation, you could convert it to a binary NSData using a routine like the one here: https://stackoverflow.com/a/26502285/1271826
Once you have a NSData, you could build your base 64 string:
let hexString = "BA5E64C0DE"
let binaryData = hexString.dataFromHexadecimalString()
let base64String = binaryData?.base64EncodedStringWithOptions(nil)
That generates the desired output, ul5kwN4=.
First, convert Hex String to Data using the following routine. (Worked in Swift 3.0.2)
extension String {
/// Expanded encoding
///
/// - bytesHexLiteral: Hex string of bytes
/// - base64: Base64 string
enum ExpandedEncoding {
/// Hex string of bytes
case bytesHexLiteral
/// Base64 string
case base64
}
/// Convert to `Data` with expanded encoding
///
/// - Parameter encoding: Expanded encoding
/// - Returns: data
func data(using encoding: ExpandedEncoding) -> Data? {
switch encoding {
case .bytesHexLiteral:
guard self.characters.count % 2 == 0 else { return nil }
var data = Data()
var byteLiteral = ""
for (index, character) in self.characters.enumerated() {
if index % 2 == 0 {
byteLiteral = String(character)
} else {
byteLiteral.append(character)
guard let byte = UInt8(byteLiteral, radix: 16) else { return nil }
data.append(byte)
}
}
return data
case .base64:
return Data(base64Encoded: self)
}
}
}
Then, convert Data to Base64 String using Data.base64EncodedString(options:).
Usage
let base64 = "BA5E64C0DE".data(using: .bytesHexLiteral)?.base64EncodedString()
if let base64 = base64 {
print(base64)
// Prints "ul5kwN4="
}

Resources