diff -Nur a/lib/mini_magick/image.rb b/lib/mini_magick/image.rb
--- a/lib/mini_magick/image.rb	2022-02-24 19:57:09.378499137 +0800
+++ b/lib/mini_magick/image.rb	2022-02-24 20:01:25.738826593 +0800
@@ -82,15 +82,30 @@
     def self.open(path_or_url, ext = nil, options = {})
       options, ext = ext, nil if ext.is_a?(Hash)
 
-      uri = URI(path_or_url.to_s)
+      # Don't use Kernel#open, but reuse its logic
+      openable =
+        if path_or_url.respond_to?(:open)
+          path_or_url
+        elsif path_or_url.respond_to?(:to_str) &&
+              %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ path_or_url &&
+              (uri = URI.parse(path_or_url)).respond_to?(:open)
+          uri
+        else
+          options = { binmode: true }.merge(options)
+          Pathname(path_or_url)
+        end
 
-      ext ||= File.extname(uri.path)
+      if openable.is_a?(URI::Generic)
+        ext ||= File.extname(openable.path)
+      else
+        ext ||= File.extname(openable.to_s)
+      end
       ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon
 
-      if uri.is_a?(URI::HTTP) || uri.is_a?(URI::FTP)
-        uri.open(options) { |file| read(file, ext) }
+      if openable.is_a?(URI::Generic)
+        openable.open(options) { |file| read(file, ext) }
       else
-        File.open(uri.to_s, "rb", options) { |file| read(file, ext) }
+        openable.open(**options) { |file| read(file, ext) }
       end
     end
 
