Dosyanın tamamını okumadan resim boyutlarını alma
Orada resim boyutlarını almak için ucuz bir yoldur (png, jpg ...)? Tercihen, bunu başarmak için sadece standart bir sınıf kitaplığı (hosting kısıtlamalar nedeniyle) kullanmak istiyorum. Resim Başlığı okuyup kendimi ayrıştırmak için nispeten kolay olmalıdır biliyorum, ama böyle bir şey zaten olması gibi görünüyor. Ayrıca, aşağıdaki kod parçası tüm görüntü istemiyorum) okur olduğunu teyit ettik:
using System;
using System.Drawing;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Image img = new Bitmap("test.png");
System.Console.WriteLine(img.Width " x " img.Height);
}
}
}
CEVAP
En iyi bahis her zaman olduğu gibi iyi test edilmiş bir kütüphane bulmak. Ancak, bu zor bir şey, burada davalar adil bir dizi için çalışması gerektiğini büyük ölçüde denenmemiş bazı tehlikeli kod söylemiştin:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
namespace ImageDimensions
{
public static class ImageHelper
{
const string errorMessage = "Could not recognize image format.";
private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
{
{ new byte[]{ 0x42, 0x4D }, DecodeBitmap},
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
{ new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
{ new byte[]{ 0xff, 0xd8 }, DecodeJfif },
};
/// <summary>
/// Gets the dimensions of an image.
/// </summary>
/// <param name="path">The path of the image to get the dimensions of.</param>
/// <returns>The dimensions of the specified image.</returns>
/// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
public static Size GetDimensions(string path)
{
using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
{
try
{
return GetDimensions(binaryReader);
}
catch (ArgumentException e)
{
if (e.Message.StartsWith(errorMessage))
{
throw new ArgumentException(errorMessage, "path", e);
}
else
{
throw e;
}
}
}
}
/// <summary>
/// Gets the dimensions of an image.
/// </summary>
/// <param name="path">The path of the image to get the dimensions of.</param>
/// <returns>The dimensions of the specified image.</returns>
/// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
public static Size GetDimensions(BinaryReader binaryReader)
{
int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
byte[] magicBytes = new byte[maxMagicBytesLength];
for (int i = 0; i < maxMagicBytesLength; i = 1)
{
magicBytes[i] = binaryReader.ReadByte();
foreach(var kvPair in imageFormatDecoders)
{
if (magicBytes.StartsWith(kvPair.Key))
{
return kvPair.Value(binaryReader);
}
}
}
throw new ArgumentException(errorMessage, "binaryReader");
}
private static bool StartsWith(this byte[] thisBytes, byte[] thatBytes)
{
for(int i = 0; i < thatBytes.Length; i = 1)
{
if (thisBytes[i] != thatBytes[i])
{
return false;
}
}
return true;
}
private static short ReadLittleEndianInt16(this BinaryReader binaryReader)
{
byte[] bytes = new byte[sizeof(short)];
for (int i = 0; i < sizeof(short); i = 1)
{
bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
}
return BitConverter.ToInt16(bytes, 0);
}
private static int ReadLittleEndianInt32(this BinaryReader binaryReader)
{
byte[] bytes = new byte[sizeof(int)];
for (int i = 0; i < sizeof(int); i = 1)
{
bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
}
return BitConverter.ToInt32(bytes, 0);
}
private static Size DecodeBitmap(BinaryReader binaryReader)
{
binaryReader.ReadBytes(16);
int width = binaryReader.ReadInt32();
int height = binaryReader.ReadInt32();
return new Size(width, height);
}
private static Size DecodeGif(BinaryReader binaryReader)
{
int width = binaryReader.ReadInt16();
int height = binaryReader.ReadInt16();
return new Size(width, height);
}
private static Size DecodePng(BinaryReader binaryReader)
{
binaryReader.ReadBytes(8);
int width = binaryReader.ReadLittleEndianInt32();
int height = binaryReader.ReadLittleEndianInt32();
return new Size(width, height);
}
private static Size DecodeJfif(BinaryReader binaryReader)
{
while (binaryReader.ReadByte() == 0xff)
{
byte marker = binaryReader.ReadByte();
short chunkLength = binaryReader.ReadLittleEndianInt16();
if (marker == 0xc0)
{
binaryReader.ReadByte();
int height = binaryReader.ReadLittleEndianInt16();
int width = binaryReader.ReadLittleEndianInt16();
return new Size(width, height);
}
binaryReader.ReadBytes(chunkLength - 2);
}
throw new ArgumentException(errorMessage);
}
}
}
Umarım bu kod oldukça açık. Ekle yeni bir dosya biçimi Ekle imageFormatDecoders
anahtar bir dizi "sihirli bit" belirir başında her dosya adı, biçimi ve değeri olan bir fonksiyonu olan özler boyutu akışı. En biçimleri tek gerçek gıcık jpeg yeterince basit.
UİScrollview alma dokunma olayları...
Sdcard bitmap resim dosyası okunurken,...
İmageView içine sığacak Görüntü, en bo...
R sıkıştırılmış veri dosyası indirmek ...
Nasıl bir alma kitaplığı oluşturmak mı...