我有一个Python脚本,使用tinypng api递归转换图像,由于某种原因它不起作用,我得到:
UnicodeDecodeError:'ascii'编解码器无法解码位置0的字节0xff:序数 不在范围内(128)
我做错了什么?
import os
import base64
from os.path import dirname
from urllib2 import Request, urlopen
from base64 import b64encode
compress_png = True
compress_jpg = True
import_dir = '666\product'
output_dir = '666\product'
tiny_png_key = 'xxxxxx'
tiny_png_url = 'https://api.tinypng.com/shrink'
img_count = 0
file_count = 0
compress_count = 0
existing_count = 0
def compressImage(filepath, filedest, overwrite = True):
global compress_count
global existing_count
if not os.path.isfile(filedest) or overwrite:
status = ''
request = Request(tiny_png_url, open(filepath, "rb").read())
auth = b64encode(bytes("api:" + tiny_png_key)).decode("ascii")
request.add_header("Authorization", "Basic %s" % auth)
response = urlopen(request)
if response.getcode() == 201:
status = "success";
headers = response.info()
result = urlopen(headers["Location"]).read()
if not os.path.exists(os.path.dirname(filedest)):
os.makedirs(os.path.dirname(filedest))
open(filedest, "wb").write(result)
compress_count += 1
else:
status = "failed"
print 'Compressing: %s\nFile: %s\nStatus: %s\n'%(filepath, img_count, status)
else:
existing_count += 1
# loop througs files in import_dir recursively
for subdir, dirs, files in os.walk(import_dir):
for file in files:
filepath = os.path.join(subdir, file)
fileName, fileExtension = os.path.splitext(file)
file_count += 1
if(fileExtension == '.png' and compress_png) or (fileExtension == '.jpg' and compress_jpg):
img_count += 1
filedest = filepath.replace(import_dir, output_dir)
compressImage(filepath, filedest)
print '================'
print 'Total Files: %s'%(file_count)
print 'Total Images: %s'%(img_count)
print 'Images Compressed: %s'%(compress_count)
print 'Images Previously Compressed (Exist in output directory): %s'%(existing_count)
完整错误:
Traceback (most recent call last):
File "C:\Users\Vygantas\Desktop\test.py", line 55, in <module> compressImage(filepath, filedest)
File "C:\Users\Vygantas\Desktop\test.py", line 28, in compressImage response = urlopen(request)
File "C:\Python27\lib\urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout)
File "C:\Python27\lib\urllib2.py", line 391, in open response = self._open(req, data)
File "C:\Python27\lib\urllib2.py", line 409, in _open '_open', req)
File "C:\Python27\lib\urllib2.py", line 369, in _call_chain result = func(*args)
File "C:\Python27\lib\urllib2.py", line 1181, in https_open return self.do_open(httplib.HTTPSConnection, req)
File "C:\Python27\lib\urllib2.py", line 1142, in do_open h.request(req.get_method(), req.get_selector(), req.data, headers)
File "C:\Python27\lib\httplib.py", line 946, in request self._send_request(method, url, body, headers)
File "C:\Python27\lib\httplib.py", line 987, in _send_request self.endheaders(body)
File "C:\Python27\lib\httplib.py", line 940, in endheaders self._send_output(message_body)
File "C:\Python27\lib\httplib.py", line 801, in _send_output msg += message_body UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
答案 0 :(得分:1)
使用网站上的示例并以与您相同的方式将其调整为Python 2似乎对我有用:
from os.path import dirname
from urllib2 import Request, urlopen
from base64 import b64encode
key = "xxxx_xxxx"
input = "NLMK.png"
output = "tiny-output.png"
request = Request("https://api.tinypng.com/shrink", open(input, "rb").read())
auth = b64encode("api:" + key).decode("ascii")
request.add_header("Authorization", "Basic %s" % auth)
response = urlopen(request)
if response.getcode() == 201:
# Compression was successful, retrieve output from Location header.
headers = response.info()
result = urlopen(headers["Location"]).read()
open(output, "wb").write(result)
else:
# Something went wrong! You can parse the JSON body for details.
print("Compression failed")
答案 1 :(得分:0)
您必须对数据进行编码,但不对用户名进行编码 我会尝试类似的东西:
def compressImage(filepath, filedest, overwrite = True):
global compress_count
global existing_count
if not os.path.isfile(filedest) or overwrite:
status = ''
data = open(filepath, "rb").read()
data = base64.b64encode(data)
request = Request(tiny_png_url, data)
request.add_header("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
auth = "api:" + tiny_png_key
request.add_header("Authorization", "Basic %s" % auth)
response = urlopen(request)