How to create a .png file using python? - python
I am trying to create a .png file from uint8array but am not getting the expected result. The file is 908 bytes but it is supposed to be of 905 bytes. When I try to open the image in the MS paint, it says This is not a valid bitmap file. The same array works for me when I use node.js. Here is the code :
import io
import numpy as np
arr =[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,200,0,0,0,200,8,6,0,0,0,173,88,174,158,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,3,43,73,68,65,84,120,156,237,221,193,110,163,48,20,64,209,206,168,255,255,203,51,251,44,174,21,192,177,33,231,236,41,52,237,149,37,30,14,63,63,0,0,0,0,0,0,0,0,0,0,19,253,57,120,220,191,75,175,98,236,232,117,114,15,219,254,63,253,157,121,21,112,119,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,191,147,126,174,185,5,239,184,250,255,229,178,185,138,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,172,103,177,222,245,233,61,201,239,58,251,172,208,236,223,111,247,235,59,107,217,179,125,86,16,8,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,71,231,32,159,190,47,61,251,124,103,231,0,163,227,103,207,41,102,159,127,247,207,255,213,101,215,107,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,126,144,179,102,207,1,70,86,239,199,88,253,93,200,171,63,255,105,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,158,50,7,89,125,159,253,238,251,49,206,218,253,250,14,179,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,184,203,28,228,238,239,175,56,59,39,89,189,223,98,247,207,127,26,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,199,62,199,255,97,171,223,15,226,239,56,137,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,183,236,7,121,250,126,139,213,251,77,86,127,126,211,88,65,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,236,50,7,217,125,63,197,234,227,207,90,125,254,145,109,175,207,10,2,65,32,16,4,2,65,32,16,4,2,65,32,16,4,2,97,245,253,239,171,124,251,156,98,245,241,35,179,247,243,76,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,246,125,252,145,217,63,223,249,207,157,127,25,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,109,239,63,191,184,251,126,135,167,255,252,213,199,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,151,57,200,200,234,253,32,171,143,31,121,202,223,249,227,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,238,242,158,244,145,213,239,175,152,109,245,251,73,86,179,31,4,118,36,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,228,233,251,37,118,127,255,198,215,206,97,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,118,153,131,220,253,62,253,232,252,187,127,111,214,89,219,190,223,227,44,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,93,230,32,171,239,227,143,172,126,15,249,200,234,57,195,234,243,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,116,14,242,233,231,255,87,239,167,120,250,123,216,71,118,159,83,189,186,236,243,176,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,56,122,127,252,177,223,131,196,35,152,131,192,39,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,204,250,110,222,171,247,48,123,182,235,217,182,221,243,110,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,1,0,0,0,0,0,0,0,0,56,239,63,169,44,80,125,75,214,2,231,0,0,0,0,73,69,78,68,174,66,96,130]
arr = np.array(arr, dtype=np.uint8)
np.set_printoptions(formatter={'int':hex})
arr=np.array(arr)
f=open("QR icon.png","w")
f.write(arr)
f.close()
Also when I open the created image in notepad, there is an extra space which is not there in the file I created using node. I think I am creating the file in a wrong way. Please help me .....
Okay, first your code didn't work for me i run into a few small errors. When i fixed them, it solved you initial problem:
import io
import numpy as np
arr =[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,200,0,0,0,200,8,6,0,0,0,173,88,174,158,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,3,43,73,68,65,84,120,156,237,221,193,110,163,48,20,64,209,206,168,255,255,203,51,251,44,174,21,192,177,33,231,236,41,52,237,149,37,30,14,63,63,0,0,0,0,0,0,0,0,0,0,19,253,57,120,220,191,75,175,98,236,232,117,114,15,219,254,63,253,157,121,21,112,119,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,191,147,126,174,185,5,239,184,250,255,229,178,185,138,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,172,103,177,222,245,233,61,201,239,58,251,172,208,236,223,111,247,235,59,107,217,179,125,86,16,8,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,71,231,32,159,190,47,61,251,124,103,231,0,163,227,103,207,41,102,159,127,247,207,255,213,101,215,107,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,126,144,179,102,207,1,70,86,239,199,88,253,93,200,171,63,255,105,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,158,50,7,89,125,159,253,238,251,49,206,218,253,250,14,179,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,184,203,28,228,238,239,175,56,59,39,89,189,223,98,247,207,127,26,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,199,62,199,255,97,171,223,15,226,239,56,137,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,183,236,7,121,250,126,139,213,251,77,86,127,126,211,88,65,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,236,50,7,217,125,63,197,234,227,207,90,125,254,145,109,175,207,10,2,65,32,16,4,2,65,32,16,4,2,65,32,16,4,2,97,245,253,239,171,124,251,156,98,245,241,35,179,247,243,76,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,246,125,252,145,217,63,223,249,207,157,127,25,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,109,239,63,191,184,251,126,135,167,255,252,213,199,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,151,57,200,200,234,253,32,171,143,31,121,202,223,249,227,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,238,242,158,244,145,213,239,175,152,109,245,251,73,86,179,31,4,118,36,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,228,233,251,37,118,127,255,198,215,206,97,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,118,153,131,220,253,62,253,232,252,187,127,111,214,89,219,190,223,227,44,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,93,230,32,171,239,227,143,172,126,15,249,200,234,57,195,234,243,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,116,14,242,233,231,255,87,239,167,120,250,123,216,71,118,159,83,189,186,236,243,176,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,56,122,127,252,177,223,131,196,35,152,131,192,39,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,204,250,110,222,171,247,48,123,182,235,217,182,221,243,110,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,1,0,0,0,0,0,0,0,0,56,239,63,169,44,80,125,75,214,2,231,0,0,0,0,73,69,78,68,174,66,96,130]
arr = np.array(arr, dtype=np.uint8)
np.set_printoptions(formatter={'int':hex})
arr=np.array(arr)
f=open("QR icon.png","wb")
f.write(arr.tostring())
f.close()
The difference is the wb so that i can write binary and the arr.tostring(). When i checked the properties it had the 905 pixels.
Related
How do I create image from binary data BSQ?
I've got a problem. I'm trying create image from binary data which I got from hyperspectral camera. The file which I have is in BSQ uint16 format. From the documentation I found out that images contained in the file (.dat) have a resolution of 1024x1024 and there are 24 images in total. The whole thing is to form a kind of "cube" which I want use in the future to creat multi-layered orthomosaic. I would also like to add that I am completely new in python but I try to be up to date with everything I need. I hope that everything what I have written is clear and uderstandable. At first I tried to use Numpy liblary to creating 3D array but ended up with an arrangement of random pixels. from PIL import Image import numpy as np file=open('Sequence 1_000021.dat','rb') myarray=np.fromfile(file,dtype=np.uint16) print('Size of new array',":", len(myarray)) con_array=np.reshape(myarray,(24,1024,1024),'C') naPIL=Image.fromarray(con_array[1,:,:]) naPIL.save('naPIL.tiff') The result: enter image description here Example of image which I want to achieve (thumbnail): enter image description here
As suspected it's just byte order, I get a sensible looking image when running the following code in a Jupyter notebook: import numpy as np from PIL import Image # open as big-endian, convert to native order, then reshape as appropriate raw = np.fromfile( './Sequence 1_000021.dat', dtype='>u2' ).astype('uint16').reshape((24, 1024, 1024)) # display inline Image.fromarray(raw[1,:,:])
numpy.fromfile seems to be unable to read large files
I wanted to write some very simple python helper tool for my project which is reading binary data from an ECG record. I have found somewhere that numpy.fromfile is the most appropriate tool to approach it, so I wrote: #!/usr/bin/env python3 import sys import numpy as np arrayOfNums = np.fromfile(sys.argv[1], 'short') print("Converting " + sys.argv[1] + "...") conversionOutput = open("output", "x") conversionOutput.write(np.array2string(arrayOfNums, separator=' ')) conversionOutput.close() print("Conversion done.") I did that to write the data which is 2 byte records unseparated. The input file is somewhat large for a simple text file (over 7MB), however not large enough I think to cause numpy troubles. The output I got in the file: [-32243 -32141 -32666 ... -32580 -32635 -32690] Why the dots between? It seems to convert it okay, but omits almost everything it is supposed to save. Any help would be appreciated.
Numpy reads correctly your file. To avoid a long display, numpy uses the dots: import numpy as np a = np.random.random(10000) Output: >>> a array([0.20902653, 0.80097215, 0.06909818, ..., 0.5963183 , 0.94024005, 0.31870234]) >>> a.shape (10000,) a contains 10000 values and not only the 6 displayed values. Update To display the full output: import sys np.set_printoptions(threshold=sys.maxsize) print(a)
How do I encode a numpy array to a base64-encoded PNG without writing to disk?
I want to convert an image, represented as a numpy array, into a base64-encoded PNG string, without writing it as a file to disk first. The goal is to send this over HTTP, and then display the image in a browser using Javascript. Basically trying to send a numpy image array to a browser without using disk. I'm very comfortable on the python side, and quite unfamiliar on the JS side. I don't want to use disk, and I don't want to use tensorflow (which has a related helper API). I have tried researching, but everything that converts a numpy array to a PNG seems to want to save it to disk. I don't know how to avoid the disk I/O.
Many functions that create files will accept an instance of io.StringIO or io.BytesIO instead of a filename or file object. Here's an example (in an ipython session) where I use numpngw.write_png (from numpngw, a package I wrote for creating PNG and animated PNG files from numpy arrays) to create a base64-encoded PNG file in a Python bytes object. First, the imports: In [39]: import numpy as np In [40]: from numpngw import write_png In [41]: import io In [42]: import base64 Create an image to work with: In [43]: img = np.random.randint(0, 256, size=(16, 16, 3)).astype(np.uint8) Create a BytesIO object, and write the PNG "file" to it. In [44]: f = io.BytesIO() In [45]: write_png(f, img) f.getvalue() gets the bytes in the PNG "file". Take a peek at the first 12 bytes: In [46]: f.getvalue()[:12] Out[46]: b'\x89PNG\r\n\x1a\n\x00\x00\x00\r' Finally, use one of the many encodings available in the base64 library to encode the PNG data: In [47]: b64 = base64.b64encode(f.getvalue()) In [48]: b64 Out[48]: b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAInRFWHRDcmVhdGlvbiBUaW1lADIwMTktMTAtMThUMDI6NDY6MTRayfRM7AAAAFF0RVh0U29mdHdhcmUAbnVtcG5ndyAodmVyc2lvbiAwLjAuOS5kZXYwKSwgaHR0cHM6Ly9naXRodWIuY29tL1dhcnJlbldlY2tlc3Nlci9udW1wbmd3aGhwYwAAAxtJREFUeJwBEAPv/AChDcGkLZrMNsaw4b5CRQk90PGcAA05N+8BH3rlSGZVLOn/vleX3mclnyfC1TXEOJYAfLtv7F3kSclGhnJDU93XTTWA2RcAutMYkETtG2kUZMWvbSDAxm0uSm8y0Do6gNQpANrN6Xt3cIoybwKclwb9jEQoIrdE6acAd4IoaaSEuH2mUIZ0tQ5plhBU61nCj7jBqQBQFH2x7wd5HR3IA5jo/jOrlalRhR2xgYRboyOl+MhIxExUhNjqEpz66SGJQNbUrWoAYQIWoEgFXiewRwACPUd35eo0DxDWYcrONkmj1fBGe03/JirvaJLQ79F7uAG2vrCXACLBrKntrzxPLoFa7Wgzl1nNEdo7Fenn7Jd+d2TAAMFELJTkhXAhUpQe3NyIjY9y+QD0Lmn11S/UYf4BcTqE3lMbbQ2iQpS1kcKOtbC2zjx7KovsK1M+JRIClOUzATlVnp8ANJS/zfP2ZTzR4dKjV2XfF3bxFs9Kk9qb+ilBHlBUSr2VA6CHxxVtcuvlkeiDvSA6AFQjA+Hd5vsgjgAcEUPkJx2SgqazSjXcSFFyQHqhgif47p3WOVM2lv0rWc4kSRwE5QCXsYTzOWusqZPbHxZSIWDvPjZcESUQ6FKZ4Pa0XFfdD2rLxp/4PF6w33k75h6uHpMAJWGC0yVRXBRW726WM9BAoX7+KjhLaJ6FhJ5aeRYL092uW8DxFwgPTq/evQg6PgOZAOWyz+saW+gMZukrMeZyQLQcQ5QMzX0sFXBtT7rAs9sEKUIx/HLH6wuTCd+zkzbvbAD6cNATGxklmLG15gwnLIX5bSCFD3wTAhDZwaXTdvUDt6LGc7oma5QfuVKUPGXtm7MAIghIuKbNd6S1wsqG6Ga/cB+wMJYklc5AG4dGzFnK+RbpACrQtchNn9v6o2zXJxjaAIaIY6VW1Db6VNeP/tXKHrusaqy1lssoVdSNGiDMo17vmM4EsTkqSkNMFAMct78+WQCb6h4CwetL6rzaQvUx03qW4GBgPbIEMe2MIS9l7D53VKdtUjhpl28zOqI5bW3YFN4cXne4IEUrgwAAAABJRU5ErkJggg=='
Python error : index out of bounds
I was curious about image processing with python, so I found this great library imageio, I tried to manipulate the pixels of a picture and save them in a new file, but i had some problems with the loops this is what the code looks like enter image description here and this the error that i Got ! IndexError: index 3507 is out of bounds for axis 0 with size 3507 the code : # -*- coding: iso-8859-1 -*- import imageio import numpy as np im = imageio.imread("JAFFRE009a.png") taille=im.shape #taille is a tuple (Width,Height) print taille # (4961,3507) matrice_pixels=open("matrice.txt",'w') for i in range(taille[1]): line="" for j in range(taille[0]): line+=repr(im[i][j]) matrice_pixels.write(line+'\n') matrice_pixels.close()
Because your image doesn't have squarred shape, reshape it before you go through your loop
EDIT We can iterate through each row/column position and save to a file as below.It will take very long time depending upon file size. Instead of writing your own function, you may want to take advantage of inbuilt binary save (which is more efficient) as np.save('matrix.py', np_array) You can load this file as np array and manipulate Or as a text file using np.save [ will take longer ] np.save('matrix.txt', np_array) Working Code: import imageio import numpy as np im = imageio.imread("9v9zU.png") matrice_pixels=open("matric.txt","wb") nx,ny = im.shape for i in range(nx): line="" for j in range(ny): line+=repr(im[i][j]) matrice_pixels.write(line+'\n') matrice_pixels.close() #Save as Binary data np.save('matrix1.npy', im) #Save as Human readable data np.savetxt('matrix1.txt', im) Alternately, you may want to look into off the shelf libraries that will do what you are intending to do. For e.g. This SO link discusses how to remove section of the picture based upon its color using PIL library. Also , in future, please DO NOT post a picture of your code. Copy/pase to SO window so that we can copy and modify. In this case I had write everything down line by line to test(thankfully code was not that long).
Trying to read numpy array into opencv - cv2.imdecode returns empty argument
Just getting back into coding after a few years out. Trying to write a piece of code that can go through a folder with .fits files, read out the image data, convert them to an array, read them into opencv, then perform edge detection on them. I can get it working fine with .png files as I don't have to play with arrays. I've done a lot of reading about, and that's enabled me to get to this point. Problem is, img is currently being returned empty, which causes everything else to freak. Any ideas please? Any help would be gratefully received! #import packages import cv2 from matplotlim import pyplot as plt import os from astropy.io import fits from skimage import img_as_uint import numpy as np #create array with filenames data = [] for root, dirs, files in os.walk(r'/Users/hannah/Desktop/firefountain-testset'): for file in files: if file.endswith('.fits'): data.append(file) #start my loop through the folder for i in data: fn = i #read fits image data hdulist = fits.open(fn) img_data = hdulist[1].data #put fits data into array with dtype set as original imgraw=np.array(img_data, dtype = np.uint8) #convert to uint16 img = img_as_uint(imgraw) #crop to area of interest then add into array - possibly don't need second line imgcrop = img[210:255,227:277] imgcroparr = np.array(imgcrop) #attempt to read into cv2 - this is where it loses the data #all fine before this point I believe imgfinal = cv2.imdecode(imgcroparr, 0,) plt.imshow(imgfinal) #imgfinal returns blank. google drive with .fits files I'm using, plus .png to show what they should look like Updated my code for i in data: fn = i imgraw = fits.getdata(fn) imgcrop = imgraw[210:255,227:277] img = cv2.imdecode(imgcrop, 0,) plt.imshow(img) This opens the fits files no issue and imgcrop works as expected. cv2.imdecode(imgcrop, 0), however, throws up the following: error: /Users/jhelmus/anaconda/conda-bld/work/opencv-2.4.8/modules/highgui/src/loadsave.cpp:307: error: (-215) buf.data && buf.isContinuous() in function imdecode_ Can't find anything on this error in this context online, getting more and more confused. It's probably something very silly and basic that I've forgotten to do, but I can't see it.