@@ -2,12 +2,10 @@ import fetch from "node-fetch";
2
2
import { encode } from "blurhash" ;
3
3
import sharp from 'sharp' ;
4
4
import sizeOf from "image-size" ;
5
- import { URL } from 'url' ;
6
5
7
6
export interface IOptions {
8
7
size ?: number ;
9
8
offline ?: boolean ;
10
- timeout ?: number ;
11
9
}
12
10
13
11
export interface IOutput {
@@ -17,89 +15,70 @@ export interface IOutput {
17
15
}
18
16
19
17
/**
20
- * ** Generate a Blurhash string from a given image URL or local path.**
18
+ * Generate a Blurhash string from a given image URL or local path.
21
19
*
22
20
* @param {string } source - The image URL or local path to the image file.
23
21
* @param {IOptions } [options] - The optional configuration options.
24
22
* @param {number } [options.size=32] - The desired size of the image for encoding the Blurhash.
25
23
* @param {boolean } [options.offline=false] - Set to `true` if the image source is a local path, `false` if it's a URL.
26
- * @param {number } [options.timeout=30000] - Timeout in milliseconds for fetch requests.
27
24
* @returns {Promise<IOutput> } The Promise that resolves to the encoded Blurhash string, along with the image width and height.
28
- * @throws {Error } If the source is invalid or if there's an error processing the image.
25
+ * @default size 32
26
+ * @default offline false
27
+ * @example
28
+ * ```js
29
+ * import { blurhashFromURL } from "blurhash-from-url";
30
+ *
31
+ * const output = await blurhashFromURL("https://i.imgur.com/NhfEdg2.png", {
32
+ * size: 32,
33
+ * });
34
+ *
35
+ * console.log(output);
36
+ * ```
29
37
*/
30
-
31
38
export const blurhashFromURL = async ( source : string , options : IOptions = { } ) : Promise < IOutput > => {
32
- const { size = 32 , offline = false , timeout = 30000 } = options ;
33
-
34
- if ( ! source ) {
35
- throw new Error ( "Source is required" ) ;
36
- }
37
-
38
- if ( ! offline ) {
39
- try {
40
- new URL ( source ) ;
41
- } catch {
42
- throw new Error ( "Invalid URL provided" ) ;
43
- }
44
- }
39
+ const { size = 32 , offline = false } = options ;
45
40
46
41
let width , height , returnedBuffer ;
47
42
48
- try {
49
- if ( offline ) {
50
- const fs = await import ( "fs" ) . catch ( ( ) => {
51
- throw new Error ( "Failed to import 'fs' module. Make sure you're in a Node.js environment." ) ;
52
- } ) ;
53
- const { width : localWidth , height : localHeight } = sizeOf ( source ) ;
54
- width = localWidth ;
55
- height = localHeight ;
56
- returnedBuffer = await sharp ( fs . readFileSync ( source ) ) . toBuffer ( ) ;
57
- } else {
58
- const controller = new AbortController ( ) ;
59
- const timeoutId = setTimeout ( ( ) => controller . abort ( ) , timeout ) ;
60
-
61
- try {
62
- const response = await fetch ( source , { signal : controller . signal } ) ;
63
- if ( ! response . ok ) {
64
- throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
65
- }
66
- const arrayBuffer = await response . arrayBuffer ( ) ;
67
- returnedBuffer = Buffer . from ( arrayBuffer ) ;
43
+ if ( offline ) {
44
+ const fs = await import ( "fs" ) ;
45
+ const { width : localWidth , height : localHeight } = sizeOf ( source ) ;
46
+ width = localWidth ;
47
+ height = localHeight ;
48
+ returnedBuffer = await sharp ( fs . readFileSync ( source ) ) . toBuffer ( ) ;
49
+ } else {
50
+ const response = await fetch ( source ) ;
51
+ const arrayBuffer = await response . arrayBuffer ( ) ;
52
+ returnedBuffer = Buffer . from ( arrayBuffer ) ;
68
53
69
- const { width : remoteWidth , height : remoteHeight } = sizeOf ( returnedBuffer ) ;
70
- width = remoteWidth ;
71
- height = remoteHeight ;
72
- } finally {
73
- clearTimeout ( timeoutId ) ;
74
- }
75
- }
54
+ const { width : remoteWidth , height : remoteHeight } = sizeOf ( returnedBuffer ) ;
55
+ width = remoteWidth ;
56
+ height = remoteHeight ;
57
+ }
76
58
77
- const { info, data } = await sharp ( returnedBuffer )
78
- . resize ( size , size , {
79
- fit : "inside" ,
80
- } )
81
- . ensureAlpha ( )
82
- . raw ( )
83
- . toBuffer ( {
84
- resolveWithObject : true ,
85
- } ) ;
59
+ const { info, data } = await sharp ( returnedBuffer )
60
+ . resize ( size , size , {
61
+ fit : "inside" ,
62
+ } )
63
+ . ensureAlpha ( )
64
+ . raw ( )
65
+ . toBuffer ( {
66
+ resolveWithObject : true ,
67
+ } ) ;
86
68
87
- const encoded = encode (
88
- new Uint8ClampedArray ( data ) ,
89
- info . width ,
90
- info . height ,
91
- 4 ,
92
- 4
93
- ) ;
69
+ const encoded = encode (
70
+ new Uint8ClampedArray ( data ) ,
71
+ info . width ,
72
+ info . height ,
73
+ 4 ,
74
+ 4
75
+ ) ;
94
76
95
- const output : IOutput = {
96
- encoded,
97
- width,
98
- height,
99
- } ;
77
+ const output : IOutput = {
78
+ encoded,
79
+ width,
80
+ height,
81
+ } ;
100
82
101
- return output ;
102
- } catch ( error ) {
103
- throw new Error ( `Failed to process image: ${ error . message } ` ) ;
104
- }
105
- } ;
83
+ return output ;
84
+ } ;
0 commit comments