السلام عليكــم ورحمـة الله وبركاتــه ،،
بصراحة اسف لإني لم اعرف اين اضع الموضوع
باختصار انا قمت ببناء MIDlet من اجل المراقبة الصحية في مدينة الرياض و قد ادخلت فيه عملية التوقيع الرقمي
حيث ان صاحب المحل بعد انتهاء عملية التفتيش على محله يطلب المراقب منه ان يقوم بالتوقيع على الPDA
طبعا عملية التوقيع هي عبارة عن تتبع لحركات المؤشر ورسم الخطوط بين هذه النقاط وطبعا العملية تتم باستخدام ال Canvas
المشكلة هي اني اريد تحويل الCanvas بعد عملية رسم التوقيع الى صورة باللامتداد PNG
قمت بعملية التحويل بعد جهد جهيد و كانت في البداية الحجم ضخم جدا لإني اعتمدت على محول لل PNG يعطي 32bit حيث وصل حجم الصورة الى 300k تقريبا
ثم قمت بتعديل هذا المحول ليعطي 8bit و حصلت على الحجم 60k تقريبا
مااريده الان هو تعديله ليعطي 1bit او 2bit حتى احصل على حجم صغير اتوقع ان يكون (7k)
لم اعرف المكان المناسب لوضع هذا الموضوع فوضعته هنا بحكم اني اكتب في هذا القسم عادة
المطلوب : لو كان هنالك احد قد تعامل مع برمجة الصور او يعلم منتدى يناقش فيه مثل هذا الامور ان لايبخل علي بالمعلومة
chunk.writeByte(8); // Bitdepth
chunk.writeByte(0); // Colortype ARGB
في حال كان المراد الحصول على ال ARGB يتم تحويل السطرين السابقين في الكود الى :
chunk.writeByte(8); // Bitdepth
chunk.writeByte(6); // Colortype ARGB
حيث انا الاول هو عدد البيتات لكل لون اي لكل لون 8bit اي 1Byte و الثاني هو الالوان حيث ان 0 يشير الى grayscale و 6 هو عبارة عن 4 + 2 اي ال RGB بالاضافة الى قناة ال alpha
ونغير الMethod التاليه فقط من اجل تغير طول الصورة لاحظو السطر byte[] raw = new byte[4*(width*height) + height];
ومن اجل اضافة قنوات الالوان و قناة alpha لاحظوا هذه الاسطر ايضا
raw[dest++] = green[source];
raw[dest++] = blue[source];
raw[dest++] = alpha[source++];
public static byte[] createDataChunk(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
{
int source = 0;
int dest = 0;
byte[] raw = new byte[4*(width*height) + height];
for (int y = 0; y < height; y++)
{
raw[dest++] = 0; // No filter
for (int x = 0; x < width; x++)
{
raw[dest++] = red[source];
raw[dest++] = green[source];
raw[dest++] = blue[source];
raw[dest++] = alpha[source++];
}
}
return toChunk("IDAT", toZLIB(raw));
}import java.io.*;
public class PNG
{
public static byte[] toPNG(int width, int height, byte[] photo) throws IOException
{
byte[] signature = new byte[] {(byte) 137, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10};
byte[] header = createHeaderChunk(width, height);
byte[] data = createDataChunk(width, height, photo,null,null,null);
byte[] trailer = createTrailerChunk();
ByteArrayOutputStream png = new ByteArrayOutputStream(signature.length + header.length + data.length + trailer.length);
png.write(signature);
png.write(header);
png.write(data);
png.write(trailer);
return png.toByteArray();
}
public static byte[] createHeaderChunk(int width, int height) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(13);
DataOutputStream chunk = new DataOutputStream(baos);
chunk.writeInt(width);
chunk.writeInt(height);
chunk.writeByte(8); // Bitdepth
chunk.writeByte(0); // Colortype ARGB
chunk.writeByte(0); // Compression
chunk.writeByte(0); // Filter
chunk.writeByte(0); // Interlace
return toChunk("IHDR", baos.toByteArray());
}
public static byte[] createDataChunk(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
{
int source = 0;
int dest = 0;
byte[] raw = new byte[(width*height) + height];
for (int y = 0; y < height; y++)
{
raw[dest++] = 0; // No filter
for (int x = 0; x < width; x++)
{
raw[dest++] = alpha[source++];
}
}
return toChunk("IDAT", toZLIB(raw));
}
public static byte[] createTrailerChunk() throws IOException
{
return toChunk("IEND", new byte[] {});
}
public static byte[] toChunk(String id, byte[] raw) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 12);
DataOutputStream chunk = new DataOutputStream(baos);
chunk.writeInt(raw.length);
byte[] bid = new byte[4];
for (int i = 0; i < 4; i++)
{
bid = (byte) id.charAt(i);
}
chunk.write(bid);
chunk.write(raw);
int crc = 0xFFFFFFFF;
crc = updateCRC(crc, bid);
crc = updateCRC(crc, raw);
chunk.writeInt(~crc);
return baos.toByteArray();
}
static int[] crcTable = null;
public static void createCRCTable()
{
crcTable = new int[256];
for (int i = 0; i < 256; i++)
{
int c = i;
for (int k = 0; k < 8; k++)
{
c = ((c & 1) > 0) ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
}
crcTable = c;
}
}
public static int updateCRC(int crc, byte[] raw)
{
if (crcTable == null)
{
createCRCTable();
}
for (int i = 0; i < raw.length; i++)
{
crc = crcTable[(crc ^ raw) & 0xFF] ^ (crc >>> 8);
}
return crc;
}
/* This method is called to encode the image data as a zlib
block as required by the PNG specification. This file comes
with a minimal ZLIB encoder which uses uncompressed deflate
blocks (fast, short, easy, but no compression). If you want
compression, call another encoder (such as JZLib?) here. */
public static byte[] toZLIB(byte[] raw) throws IOException
{
return ZLIB.toZLIB(raw);
}
}
class ZLIB
{
static final int BLOCK_SIZE = 32000;
public static byte[] toZLIB(byte[] raw) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 6 + (raw.length / BLOCK_SIZE) * 5);
DataOutputStream zlib = new DataOutputStream(baos);
byte tmp = (byte) 8;
zlib.writeByte(tmp); // CM = 8, CMINFO = 0
zlib.writeByte((31 - ((tmp << 8) % 31)) % 31); // FCHECK (FDICT/FLEVEL=0)
int pos = 0;
while (raw.length - pos > BLOCK_SIZE)
{
writeUncompressedDeflateBlock(zlib, false, raw, pos, (char) BLOCK_SIZE);
pos += BLOCK_SIZE;
}
writeUncompressedDeflateBlock(zlib, true, raw, pos, (char) (raw.length - pos));
// zlib check sum of uncompressed data
zlib.writeInt(calcADLER32(raw));
return baos.toByteArray();
}
private static void writeUncompressedDeflateBlock(DataOutputStream zlib, boolean last,
byte[] raw, int off, char len) throws IOException
{
zlib.writeByte((byte)(last ? 1 : 0)); // Final flag, Compression type 0
zlib.writeByte((byte)(len & 0xFF)); // Length LSB
zlib.writeByte((byte)((len & 0xFF00) >> 8)); // Length MSB
zlib.writeByte((byte)(~len & 0xFF)); // Length 1st complement LSB
zlib.writeByte((byte)((~len & 0xFF00) >> 8)); // Length 1st complement MSB
zlib.write(raw,off,len); // Data
}
private static int calcADLER32(byte[] raw)
{
int s1 = 1;
int s2 = 0;
for (int i = 0; i < raw.length; i++)
{
int abs = raw >=0 ? raw : (raw + 256);
s1 = (s1 + abs) % 65521;
s2 = (s2 + s1) % 65521;
}
return (s2 << 16) + s1;
}
}وهذه هدية للمنتدى MIDlet يقوم بعملية التصوير وحفظ الصور وبنفس الوقت اضفت اليه Progress Bar (شريط التقدم ليس من برمجتي لكن الصور من برمجتي)
ولكم جزيل الشكر
