extract thumbnail from online video link - python

I am building a website, and I am trying to extract one image from a video directly using the link provide by a user.
The things is that all need to be done in memory: download the video in memory (using requests for example), extract an image and I upload it on my aws bucket
I have searched for a solution and found cv2. I was able locally to extract one image using:
vcap = cv2.VideoCapture(path_to_vid)
res, thumb_buf = cv2.imencode('.png', im_ar)
bt = thumb_buf.tostring()
The issue is, after some research, reading and decoding from bytes or content of response is not supported, so I am back to the beginning.
Ideally I wanted something like this:
r = requests.get(url)
vcap = cv2.VideoCapture(io.BytesIO(r.content))
res, thumb_buf = cv2.imencode('.png', im_ar)
bt = thumb_buf.tostring()

Related

Imgur changes image format

I have used python to upload an image from my desktop to imgur in the jpg format but it converts the image to jpeg format and this is no good for the use I am looking to use this for. I was wondering if anyone knows how to keep it from changing. here is my code with my keys taken out.
from imgurpython import ImgurClient
def uploadimage():
client_id = 'hi'
client_secret = 'hi'
client = ImgurClient(client_id, client_secret)
uploadedImage = client.upload_from_path(r"C:\Users\will_\Documents\PSA Card Project Files\Price Checker\IMG_1632.jpg", config=None, anon=True)
link = "{0}".format(uploadedImage['link'])
print(link)
uploadimage()
Edit: The extension is the thing that changes from .jpg to .jpeg when I go view the uploaded image. This is a problem because the website that I need this link for, requires that the image be jpg or png or another format on their list but jpeg is not one of those formats on that list.

OCR Space response ParsedResults[0] error

I am making a program in python that scans receipts and relies on an OCR response using the OCRSpace API. It has worked perfectly in that past with a couple hundred tries but when uploading an image to my flask server from an iphone instead of a computer, the image's contents do not have an OCR result. I have tried using the same image on their website and it gives a normal response but with my flask app it returns
parsed_results = result.get("ParsedResults")[0]
TypeError: 'NoneType' object is not subscriptable
I am using the code:
img = cv2.imread(file_path)
height, width, _ = img.shape
roi = img[0: height, 0: width]
_, compressedimage = cv2.imencode(".jpg", roi, [1, 90])
file_bytes = io.BytesIO(compressedimage)
url_api = "https://api.ocr.space/parse/image"
result = requests.post(url_api,
files = {os.path.join(r'PATH', file_name): file_bytes},
data = {"apikey": "KEY",
"language": "eng",
#"OCREngine": 2,
"isTable": True})
result = result.content.decode()
result = json.loads(result)
parsed_results = result.get("ParsedResults")[0]
global OCRText
OCRText = parsed_results.get("ParsedText")
Thanks for any help in advance!
iPhones and iPads as of iOS 11 use HEIF as standard; there are no incompatibilities when transferring to PC or sending e.g. by sharing, as the images are converted to the widely supported JPEG format; however, incompatibilities arise when using cloud services e.g. Google Photos.
High Efficiency Image File Format (HEIF)
As #rob247 posted IPhones are using HEIF format by default(official link here)
So when you uploaded photos to the script please try converting it to JPEG before use since opencv does not support *heif,*avif,*heic yet see issue #14534 also view the list of supported formats at opencv imread if you prefer other formats

Saving image from API Endpoint with no filetype, in python

I'm trying to save images from the Spotify API
I get album art in the form of a link:
https://i.scdn.co/image/ab67616d00004851c96f7c7b077c224975b4c5ce
I think it's a jpg file.
I run into errors in trying to display or save this in python.
I'm not even sure how I'm meant to format something like:
Do I need str around the link?
str(https://i.scdn.co/image/ab67616d00004851c96f7c7b077c224975b4c5ce)
Or should I create a new variable e.g.
image_path = 'https://i.scdn.co/image/ab67616d00004851c96f7c7b077c224975b4c5ce'
And then:
im1 = im1.save(image_path)
Your second suggestion should work with an addition of actually downloading the image using urllib.request:
import urllib.request
image_path = 'https://i.scdn.co/image/ab67616d00004851c96f7c7b077c224975b4c5ce'
urllib.request.urlretrieve(image_path, "image.jpg")

Only one image from 5 is downloaded and it knocks out an error

import requests
from PIL import Image
url_shoes_for_choice = [
"https://content.adidas.co.in/static/Product-CM7531/Unisex_OUTDOOR_SANDALS_CM7531_1.jpg",
"https://cdn.shopify.com/s/files/1/0080/1374/2161/products/product-image-897958210_640x.jpg?v=1571713841",
"https://cdn.chamaripashoes.com/media/catalog/product/cache/9/image/9df78eab33525d08d6e5fb8d27136e95/1/_/1_8_3.jpg",
"https://ae01.alicdn.com/kf/HTB1EyKjaI_vK1Rjy0Foq6xIxVXah.jpg_q50.jpg",
"https://www.converse.com/dw/image/v2/BCZC_PRD/on/demandware.static/-/Sites-cnv-master-catalog/default/dwb9eb8c43/images/a_107/167708C_A_107X1.jpg"
]
def img():
for url in url_shoes_for_choice:
image = requests.get(url, stream=True).raw
out = Image.open(image)
out.save('image/image.jpg', 'jpg')
if __name__=="__main__":
img()
Error:
OSError: cannot identify image file <_io.BytesIO object at 0x7fa185c52d58>
The problem is that one of the images is making issues with the byte data returned by the requests.get(url, stream=True).raw, I'm not sure but I guess the data of the 3rd image is invalid byte data so instead of getting the raw data we can just fetch the content and then by using BytesIO we can fix the byte data.
I fixed one more thing from your original code, I added numbering to your images so each can be saved with different name.
from io import BytesIO
def img():
for count, url in enumerate(url_shoes_for_choice):
image = requests.get(url, stream=True)
with BytesIO(image.content) as f:
with Image.open(f) as out:
# out.show() # See the images
out.save('image/image{}.jpg'.format(count))
(Though this works fine but I'm not sure what was the main issue. If anyone knows exactly what is the issue please comment and explain.)
I opened the first link in my browser and saved the image. It's actually a webp file.
$ file Unisex_OUTDOOR_SANDALS_CM7531_1.webp
Unisex_OUTDOOR_SANDALS_CM7531_1.webp: RIFF (little-endian) data, Web/P image, VP8 encoding, 500x500, Scaling: [none]x[none], YUV color, decoders should clamp
You explicitly tell the image library that it should expect a jpg. When you remove that parameter and let it figure it out on its own using out.save('image/image.jpg') the first image successfully downloads for me.
The first two images work this way if you make sure to save each under a different name:
def img():
i = 0
for url in url_shoes_for_choice:
i+=1
image = requests.get(url, stream=True).raw
out = Image.open(image)
out.save('image{}.jpg'.format(i))
the third is a valid jpeg file, as well as the fourth, but using the JFIF standard 1.01 which I hear the first time of. I'm pretty sure you'll have to figure out support for different such filetypes.
It is worth noting that if I download the images in chrome and open those with python, nothing fails. So chrome might be adding information to the file.
The documentation of PIL/pillow explains here that you need a new enough version for animated images, but that is not your problem.
Support for animated WebP files will only be enabled if the system
WebP library is v0.5.0 or later. You can check webp animation support
at runtime by calling features.check(“webp_anim”).

How to load a video from its string representation in OpenCV using Python?

I'm writing a Rest-API function which should take a video from a post request, process the video using OpenCV and return a text response. I got stuck at reading the video from its string representation.
I looked at documentations that describe how to read a video in OpenCV and all of them are either reading from a path or from the webcam. For example, cv2.VideoCapture or FileVideoStream from imutils are all using the file path to load the video. However, I want to avoid redundant IO operations and don't want to write the video to a file first.
Related part in my project:
#app.route('/processvideo', methods = ['POST'])
def process_video():
# read as string
fStr = request.files['file'].read() # file is read as string from the request
npimg = np.fromstring(fStr, np.uint8) # string data is converted to numpy array.
# image = cv2.imdecode(npimg, cv2.IMREAD_COLOR) # this functions doesn't work, because it only takes image, not video.
return jsonify( { 'output': 'test' } )
I'm sending the request in cli for test as follows:
curl -F 'file=#demo.mp4' http://localhost:5000/processvideo
I want to process the incoming video frame by frame, so I need the frames as an image. Thanks from now for any help.

Categories