encoding an image to base64 string - dart

am trying to upload image from photo gallery in dart using the library image_picker.. which is working fine ..
and then am trying to convert the selected image to bas64 string like this:
imageSelectorGallery() async {
_image = await ImagePicker.pickImage(
source: ImageSource.gallery,
// maxHeight: 50.0,
// maxWidth: 50.0,
);
List<int> imageBytes = _image.readAsBytesSync();
print(imageBytes);
String base64Image = base64Encode(imageBytes);
print('string is');
print(base64Image);
print("You selected gallery image : " + _image.path);
setState(() {});
}
but this keeps returning a not correct string .. for example:
_9j_4QG1RXhpZgAATU0AKgAAAAgABwEQAAIAAAAaAAAAYgEAAAQAAAABAAADwAEBAAQAAAABAAAFAAEyAAIAAAAUAAAAfAESAAMAAAABAAEAAIdpAAQAAAABAAAAlwEPAAIAAAAHAAAAkAAAAABBbmRyb2lkIFNESyBidWlsdCBmb3IgeDg2ADIwMTg6MTA6MTcgMTE6Mjc6NTMAR29vZ2xlAAAQgp0ABQAAAAEAAAFdgpoABQAAAAEAAAFlkpIAAgAAAAQ0NzQAkpEAAgAAAAQ0NzQAkpAAAgAAAAQ0NzQAkgoABQAAAAEAAAFtkgkAAwAAAAEAAAAAiCcAAwAAAAEAZAAAkAQAAgAAABQAAAF1kAMAAgAAABQAAAGJoAMABAAAAAEAAAUApAMAAwAAAAEAAAAAoAIABAAAAAEAAAPAkgIABQAAAAEAAAGdkgEACgAAAAEAAAGlkAAABwAAAAQwMjIwAAAAAAAAARgAAABkAJiWgDuaygAAABOIAAAD6DIwMTg6MTA6MTcgMTE6Mjc6NTMAMjAxODoxMDoxNyAxMToyNzo1MwAAAAEpAAAAZAAAGfMAAAPo_-AAEEpGSUYAAQEAAAEAAQAA_9sAQwACAQEBAQECAQEBAgICAgIEAwICAgIFBAQDBAYFBgYGBQYGBgcJCAYHCQcGBggLCAkKCgoKCgYICwwLCgwJCgoK_9sAQwECAgICAgIFAwMFCgcGBwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK_8AAEQgFAAPAAwEiAAIRAQMRAf_EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC__EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYq
and this cannot be converted to image ..
where is the problem and how to solve it?

You've only copied the first 1024 characters of the encoded string into the question. Maybe the print command truncated it. Also, the online tool seems to prefer (require?) the URL safe version, so as Günter says, use base64UrlEncode.
To confirm that the string you are using is roughly the right length, add 33%. That is, a 2k image would convert to a string roughly 2667 characters long.

Related

How to split this string in Dart? /data/data/com.example.trail/cache/IMG_1645484057312.png

I need to get the name of an image path, which is a String. How could i say programmatically in dart "when you find the first / from the right hand side split it, then give it to me"?
the string which i need to split is:
'/data/data/com.example.trail/cache/IMG_1645484057312.png'
You can use split like the #scott-deagan answer for it. But if you intend to support cross-platform path manipulation, you need to use path package.
Example:
import 'package:path/path.dart' as p;
void main() {
var filepath = '/data/data/com.example.trail/cache/IMG_1645484057312.png';
print(p.basename(filepath));
print(p.basenameWithoutExtension(filepath));
}
result:
IMG_1645484057312.png
IMG_1645484057312
void main() {
var someFile = '/data/data/com.example.trail/cache/IMG_1645484057312.png';
var fname = someFile.split('/').last;
var path = someFile.replaceAll("/$fname", '');
print(fname);
print(path);
}
Here is the way I recommend you to test
First, do the split on the original string by "/" splitter, then extract the last member of the list created by the splitter to get the name of the png file.
Second, for extracting the remaining string (i.e. the file path), use the substring method of the class string. just by subtracting the original string length from the last_member length in the previous portion, you are able to get the file path string.
Hope to be useful
Bests
void main() {
String a = '/data/data/com.example.trail/cache/IMG_1645484057312.png';
var splited_a = a.split('/');
var last_image_index = splited_a.last;
String remaining_string = a.substring(0, a.length - last_image_index.length);
print(remaining_string);
print(last_image_index);
}
result:
the result of path and file extraction from a string in dart

SHA256 hash of camera image differs after it was saved to photo album

Xcode 10.2 and Swift 5
I pick an image from camera and calculate SHA256 hash of the image as string and save the image to iPhone photo album.
//Save photo to album. Photo comes from UIImagePickerController
UIImageWriteToSavedPhotosAlbum(self.photo, self, #selector(saveimage(_:didFinishSavingWithError:contextInfo:)), nil)
//Calculate hash
let imageData : Data = self.photo!.pngData()!
let imageHash : String = getImageHash(data: imageData)
func getImageHash(data : Data) -> String {
var hashBytes = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hashBytes)
}
var hex = ""
for index in 0..<Int(CC_SHA256_DIGEST_LENGTH) {
hex += String(format: "%02x", hashBytes[index])
}
print(hex)
return hex
}
The code, however, gives me a different SHA256 of the image than after it has been saved. I transferred the photo to my Mac and checked hash by shasum -a 256 as well as uploaded it directly from iPhone to an online hash generator which gave me same hash as Mac did.
So, either my code to calculate the hash is wrong or something is being changed while storing the photo such as name or properties using UIImageWriteToSavedPhotosAlbum(...). Any ideas how to fix this?
I have done some further research on the matter and it appears that the data you have inside the UIImage is indeed different from the data that you open as a file, and I believe that is exactly what causes the problem. Note that I have shortened the base64 data, for readability.
Swift
func getImageHash(data: Data) -> String {
var hashBytes = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)
data.withUnsafeBytes {
_ = CC_SHA256($0.baseaddress, CC_LONG(data.count), &hashBytes)
}
var hex = ""
for index in 0 ..< Int(CC_SHA256_DIGEST_LENGTH) {
hex += String(format: "%02x", hashbytes[index])
}
return hex
}
The function is fine, I'll use an example using the assets folder of iOS.
let imageData = UIImage(named: "Example")!.pngData()!
print(imageData.base64EncodedString())
// 'iVBORw0KGgoAAAANSUhEUgAAAG8AAACACAQAAACv3v+8AAAM82lD [...] gAAAABJRU5ErkJggg=='
let imageHash = getImageHash(data: imageData)
print(imageHash)
// '145036245c9f675963cc8de2147887f9feded5813b0539d2320d201d9ce63397'
The hash is calculated correctly as far as we are concerned right now. I was interested in the base64 data, so I can use that on other platforms too.
Python
import hashlib
import base64
img_d = base64.b64decode('iVBORw0KGgoAAAANSUhEUgAAAG8AAACACAQAAACv3v+8AAAM82lD [...] gAAAABJRU5ErkJggg==')
m = hashlib.sha256()
m.update(img_d)
m.digest().hex()
# '145036245c9f675963cc8de2147887f9feded5813b0539d2320d201d9ce63397'
So it appears the hash is calculated correctly, but only for the base64 data. So what is the difference? Let's use Python again to investigate. I used PIL to load the image directly.
import hashlib
from PIL import Image
i = Image.open('/path/to/file')
img_d = i.tobytes()
m = hashlib.sha256()
m.update(img_d)
m.digest().hex()
# 'f650b1b95a50c3a2b77da7a0825c3c01066385a12c8fe50b449ffc8c7249e370'
So now we have, indeed, a different hash. Let's try one last thing, openssl dgst in the terminal.
Terminal
echo 'iVBORw0KGgoAAAANSUhEUgAAAG8AAACACAQAAACv3v+8AAAM82lD [...] gAAAABJRU5ErkJggg==' | base64 --decode | openssl dgst -sha256
145036245c9f675963cc8de2147887f9feded5813b0539d2320d201d9ce63397
Alright, so indeed, openssl digest can calculate the hash over the base64 data and it does indeed match.
openssl dgst -sha256 /path/to/file
SHA256(/path/to/file)= d15c2d0c186a46b41c34a312eaf1c7e4b0f7a51bdb9c53a91dc361385ba23e64
So it's very interesting. The base64 data hashed has a 100% success rate, but loading it in Python and in the terminal, resulted in two different hashes. I do not know the reason why even they are different. I do believe what I mentioned earlier in the comments is correct, hashing a file will result in a different hash, as the meta data of the file is hashed too.
In order to provide a solution: try to hash your raw image data, instead of the file. This has the biggest chance of success. Hope this helps.

How to pass varbinary(max) value as a parameter from view to actionmethod in the controller and save it to another table

I am trying to take and pass a varbinary(max) image value from the view to an action method in my controller.and trying to insert the same value to another table field. please anyone help me
This is my view
#Html.ActionLink("- Add To Wishlist", "AddToWishlist", "Products", new { id = item.ProductID,img=item.ProductImage , id2=item.ProductCategoryID}, new { onclick = "wish(id);", #class = "fa fa-heart-o" })
this is my controller
public ActionResult AddToWishlist(int id,byte[] img,int id2)
{
TBL_WishList wish = new TBL_WishList();
wish.WProductID = id;
wish.Wimage = img;
wish.WCategoryID = id2;
wish.WUserID = Convert.ToInt32(Session["UserID"].ToString());
DateTime s = DateTime.Now;
wish.WInsertDate = s;
db.TBL_WishList.Add(wish);
db.SaveChanges();
return RedirectToAction("productlistmain1");
}
ERROR:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
table design:https://i.stack.imgur.com/aXQPJ.png
Use HttpPostedFileBase img for getting the image from view to controller
In controller you have to convert image to byte[]
Which would be something like this
byte[] arr = new byte[img.ContentLength];
img.InputStream.Read(arr, 0, img.ContentLength);
You can now pass the value to your DB.
This is how image to byte[] conversion works
For your exception i think you might have converted image to byte[] and passed it as string format so c# will assume it to be base64 string
There are various online converters to convert image to byte[] and base 64 string,try them and make sure you get the same value.
i just pass the base64 as parameter and increase the limit of url string capacity it worked for me

POST base64 encoded image string to PHP

I've read through numerous posts and watched some videos.
Problem: I'm unable to POST a base64 string image to PHP server and save to MySQL database without corruption.
What I've attempted: I've attempted passing the base64 encoded string of the image just like I would pass a string or int as a POST parameter. I verified that the POST data is successfully making it to the PHP server and it is getting saved in the database. However, when I extract the base64 encoded string and decode it so the image can be rendered in the browser, it does not work. It only shows a broken image link instead of the image. It seems as though something is happening to corrupt the data in the POST process. I say this because I copied the base64 string directly from a println() statement in Xcode and pasted it into the PHP file where it was decoded and displayed perfectly. I'm able to upload base64 strings of images from my Android app perfectly fine. The problems seems to be with how I'm doing it in Swift.
After some research, I see where I may need to specify a boundary around the image parameter. I'm not positive about this though because I'm not sure if you just need a boundary specified when you send the image file directly or if you also need it when sending a base64 encoded string of the image.
Can anyone tell me if I need to set a boundary around the base64 encoded string parameter before sending it to the PHP server? Any idea what I could be doing wrong?
let image: UIImage = imgProfilePic.image!
let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(0.1, 0.1))
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)
let base64String = imageData.base64EncodedStringWithOptions(.allZeros)
var cd = CoreDataUser(pstrContext: "this")
var params = "strUsername=" + cd.getUsername()
params = params + "&strPassword=" + cd.getPassword()
params = params + "&blbProfilePic=" + base64String
Earlier I referred you to https://stackoverflow.com/a/14803292/1271826 which shows one fairly limited and tactical solution to the presence of the + characters in the base-64 string. This consisted of replacing the + characters with %2B.
But I notice that you're also including user name and password in your parameters. This would suggest that you really want a more generalized solution, percent escaping all of the reserved characters. If you don't do that, this wouldn't work if the password included reserved characters (such as + or &).
When submitting parameters like this, you should percent escape the values. For example, you might define a character set to be only the "unreserved" characters (as defined by RFC 3986), namely the alphanumeric characters plus -, ., _, and ~:
extension NSCharacterSet {
class func URLQueryValueAllowedCharacterSet() -> NSCharacterSet {
return NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")
}
}
Then you can do something like:
func percentEscapeString(string: String) -> String {
return string.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryValueAllowedCharacterSet())!
}
Or, if you like the old CFURLCreateStringByAddingPercentEscapes function, you can do:
func percentEscapeString(string: String) -> String {
return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
string,
nil,
":/?#!$&'()*+,;=",
CFStringBuiltInEncodings.UTF8.rawValue) as! String;
}
The previous examples are more intuitive, but this latter approach is a little more efficient.
But regardless of how you implement it, you can now use this function to percent escape your strings:
let params = "strUsername=" + percentEscapeString(cd.getUsername()) +
"&strPassword=" + percentEscapeString(cd.getPassword()) +
"&blbProfilePic=" + percentEscapeString(base64String)

Titanium ByteArray to image Blob

I have a list of images encoded as ByteArrays from an API to be displayed in a TableView
Here is one of the ByteArrays
i'm not managing to display an image with it,
nor saving a file or making a buffer or a stream buffer, those are some examples
var blobStream = Ti.Stream.createStream({ source: array, mode: Ti.Stream.MODE_READ });
or
var buff = Ti.createBuffer({value:array, length:array.length, type:Ti.Codec.CHARSET_UTF8});
and giving the array either to
Titanium.Utils.base64decode( array );
Titanium.Utils.base64encode( array );
crashes badly with "wrong type passed to function"
How can I make a blob out of a ByteArray and set it to an Imageview?
You can use this snippet to convert byte array in base64 string.
Decode the string with var imageBlob = Ti.Utils.base64decode(string);
and than set it in var image = Ti.UI.createImageView({ image:imageBlob });

Resources