Вы можете попробовать На этой странице . Я не тестировал его, но кажется довольно разумным, что он будет работать.
Кроме того, разные типы файлов имеют разные способы получения ширины и высоты. Попытайтесь уточнить свой вопрос.
Одна из страниц anwser:
unit ImgSize;
interface
uses Classes;
procedure GetJPGSize(const sFile: string; var wWidth, wHeight: word);
procedure GetPNGSize(const sFile: string; var wWidth, wHeight: word);
procedure GetGIFSize(const sGIFFile: string; var wWidth, wHeight: word);
implementation
uses SysUtils;
function ReadMWord(f: TFileStream): word;
type
TMotorolaWord = record
case byte of
0: (Value: word);
1: (Byte1, Byte2: byte);
end;
var
MW: TMotorolaWord;
begin
// It would probably be better to just read these two bytes in normally and
// then do a small ASM routine to swap them. But we aren't talking about
// reading entire files, so I doubt the performance gain would be worth the trouble.
f.Read(MW.Byte2, SizeOf(Byte));
f.Read(MW.Byte1, SizeOf(Byte));
Result := MW.Value;
end;
procedure GetJPGSize(const sFile: string; var wWidth, wHeight: word);
const
ValidSig : array[0..1] of byte = ($FF, $D8);
Parameterless = [$01, $D0, $D1, $D2, $D3, $D4, $D5, $D6, $D7];
var
Sig: array[0..1] of byte;
f: TFileStream;
x: integer;
Seg: byte;
Dummy: array[0..15] of byte;
Len: word;
ReadLen: LongInt;
begin
FillChar(Sig, SizeOf(Sig), #0);
f := TFileStream.Create(sFile, fmOpenRead);
try
ReadLen := f.Read(Sig[0], SizeOf(Sig));
for x := Low(Sig) to High(Sig) do
if Sig[x] <> ValidSig[x] then
ReadLen := 0;
if ReadLen > 0 then
begin
ReadLen := f.Read(Seg, 1);
while (Seg = $FF) and (ReadLen > 0) do
begin
ReadLen := f.Read(Seg, 1);
if Seg <> $FF then
begin
if (Seg = $C0) or (Seg = $C1) then
begin
ReadLen := f.Read(Dummy[0], 3); // don't need these bytes
wHeight := ReadMWord(f);
wWidth := ReadMWord(f);
end
else
begin
if not (Seg in Parameterless) then
begin
Len := ReadMWord(f);
f.Seek(Len - 2, 1);
f.Read(Seg, 1);
end
else
Seg := $FF; // Fake it to keep looping.
end;
end;
end;
end;
finally
f.Free;
end;
end;
procedure GetPNGSize(const sFile: string; var wWidth, wHeight: word);
type
TPNGSig = array[0..7] of byte;
const
ValidSig: TPNGSig = (137, 80, 78, 71, 13, 10, 26, 10);
var
Sig: TPNGSig;
f: tFileStream;
x: integer;
begin
FillChar(Sig, SizeOf(Sig), #0);
f := TFileStream.Create(sFile, fmOpenRead);
try
f.Read(Sig[0], SizeOf(Sig));
for x := Low(Sig) to High(Sig) do
if Sig[x] <> ValidSig[x] then
exit;
f.Seek(18, 0);
wWidth := ReadMWord(f);
f.Seek(22, 0);
wHeight := ReadMWord(f);
finally
f.Free;
end;
end;
procedure GetGIFSize(const sGIFFile: string; var wWidth, wHeight: word);
type
TGIFHeader = record
Sig: array[0..5] of char;
ScreenWidth, ScreenHeight: word;
Flags, Background, Aspect: byte;
end;
TGIFImageBlock = record
Left, Top, Width, Height: word;
Flags: byte;
end;
var
f: file;
Header: TGifHeader;
ImageBlock: TGifImageBlock;
nResult: integer;
x: integer;
c: char;
DimensionsFound: boolean;
begin
wWidth := 0;
wHeight := 0;
if sGifFile = '' then
exit;
{$I-}
FileMode := 0; // read-only
AssignFile(f, sGifFile);
reset(f, 1);
if IOResult <> 0 then
// Could not open file
exit;
// Read header and ensure valid file
BlockRead(f, Header, SizeOf(TGifHeader), nResult);
if (nResult <> SizeOf(TGifHeader)) or (IOResult <> 0)
or (StrLComp('GIF', Header.Sig, 3) <> 0) then
begin
// Image file invalid
close(f);
exit;
end;
// Skip color map, if there is one
if (Header.Flags and $80) > 0 then
begin
x := 3 * (1 SHL ((Header.Flags and 7) + 1));
Seek(f, x);
if IOResult <> 0 then
begin
// Color map thrashed
close(f);
exit;
end;
end;
DimensionsFound := False;
FillChar(ImageBlock, SizeOf(TGIFImageBlock), #0);
// Step through blocks
BlockRead(f, c, 1, nResult);
while (not EOF(f)) and (not DimensionsFound) do
begin
case c of
',': // Found image
begin
BlockRead(f, ImageBlock, SizeOf(TGIFImageBlock), nResult);
if nResult <> SizeOf(TGIFImageBlock) then
begin
// Invalid image block encountered
close(f);
exit;
end;
wWidth := ImageBlock.Width;
wHeight := ImageBlock.Height;
DimensionsFound := True;
end;
',' : // Skip
begin
// NOP
end;
// nothing else, just ignore
end;
BlockRead(f, c, 1, nResult);
end;
close(f);
{$I+}
end;
end.
И для BMP (также найденная на упомянутой странице):
function FetchBitmapHeader(PictFileName: String; Var wd, ht: Word): Boolean;
// similar routine is in "BitmapRegion" routine
label ErrExit;
const
ValidSig: array[0..1] of byte = ($FF, $D8);
Parameterless = [$01, $D0, $D1, $D2, $D3, $D4, $D5, $D6, $D7];
BmpSig = $4d42;
var
// Err : Boolean;
fh: HFile;
// tof : TOFSTRUCT;
bf: TBITMAPFILEHEADER;
bh: TBITMAPINFOHEADER;
// JpgImg : TJPEGImage;
Itype: Smallint;
Sig: array[0..1] of byte;
x: integer;
Seg: byte;
Dummy: array[0..15] of byte;
skipLen: word;
OkBmp, Readgood: Boolean;
begin
// Open the file and get a handle to it's BITMAPINFO
OkBmp := False;
Itype := ImageType(PictFileName);
fh := CreateFile(PChar(PictFileName), GENERIC_READ, FILE_SHARE_READ, Nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fh = INVALID_HANDLE_VALUE) then
goto ErrExit;
if Itype = 1 then
begin
// read the BITMAPFILEHEADER
if not GoodFileRead(fh, @bf, sizeof(bf)) then
goto ErrExit;
if (bf.bfType <> BmpSig) then // 'BM'
goto ErrExit;
if not GoodFileRead(fh, @bh, sizeof(bh)) then
goto ErrExit;
// for now, don't even deal with CORE headers
if (bh.biSize = sizeof(TBITMAPCOREHEADER)) then
goto ErrExit;
wd := bh.biWidth;
ht := bh.biheight;
OkBmp := True;
end
else
if (Itype = 2) then
begin
FillChar(Sig, SizeOf(Sig), #0);
if not GoodFileRead(fh, @Sig[0], sizeof(Sig)) then
goto ErrExit;
for x := Low(Sig) to High(Sig) do
if Sig[x] <> ValidSig[x] then
goto ErrExit;
Readgood := GoodFileRead(fh, @Seg, sizeof(Seg));
while (Seg = $FF) and Readgood do
begin
Readgood := GoodFileRead(fh, @Seg, sizeof(Seg));
if Seg <> $FF then
begin
if (Seg = $C0) or (Seg = $C1) or (Seg = $C2) then
begin
Readgood := GoodFileRead(fh, @Dummy[0],3); // don't need these bytes
if ReadMWord(fh, ht) and ReadMWord(fh, wd) then
OkBmp := True;
end
else
begin
if not (Seg in Parameterless) then
begin
ReadMWord(fh,skipLen);
SetFilePointer(fh, skipLen - 2, nil, FILE_CURRENT);
GoodFileRead(fh, @Seg, sizeof(Seg));
end
else
Seg := $FF; // Fake it to keep looping
end;
end;
end;
end;
ErrExit: CloseHandle(fh);
Result := OkBmp;
end;
Обновление: сентябрь 2018 г.
Вы можете использовать URLSearchParams , который прост и имеет приличную (но не полную) поддержку браузера .
const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');
] Оригинал
Для этого вам не нужен jQuery. Вы можете использовать только чистый JavaScript:
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
Использование:
// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)
Примечание. Если параметр присутствует несколько раз (? Foo = lorem & foo = ipsum
), вы получите первое значение ( lorem
). Для этого нет стандарта, и способы использования различаются, см., Например, следующий вопрос: Авторитетное положение дублирующихся ключей запроса HTTP GET .
ПРИМЕЧАНИЕ. Функция чувствительна к регистру. Если вы предпочитаете имя параметра без учета регистра, добавьте модификатор «i» в RegExp
. Это обновление, основанное на новых спецификациях URLSearchParams , чтобы добиться того же результата более лаконично. См. Ответ под названием « URLSearchParams » ниже.
Если вы используете jQuery, вы можете использовать библиотеку, например jQuery BBQ: Back Button & Query Library .
.. .jQuery BBQ предоставляет полный метод
.deparam ()
, а также управление состоянием хэша, а также служебные методы синтаксического анализа и слияния фрагментов / запросов.
Изменить: Добавление Deparam Пример:
var DeparamExample = функция () {var params = $ .deparam.querystring (); // nameofparam - это имя параметра из url // код ниже получит параметр, если ajax обновится с помощью хеша if (typeof params.nameofparam == 'undefined') {params = jQuery.deparam.fragment (window.location.href) ; } if (typeof params.nameofparam! = 'undefined' ) {var paramValue = params.nameofparam.toString (); }};
Если вы хотите использовать простой JavaScript, вы можете использовать ...
var getParamValue = (function() {
var params;
var resetParams = function() {
var query = window.location.search;
var regex = /[?&;](.+?)=([^&;]+)/g;
var match;
params = {};
if (query) {
while (match = regex.exec(query)) {
params[match[1]] = decodeURIComponent(match[2]);
}
}
};
window.addEventListener
&& window.addEventListener('popstate', resetParams);
resetParams();
return function(param) {
return params.hasOwnProperty(param) ? params[param] : null;
}
})();
Благодаря новому API истории HTML и, в частности, history.pushState ()
и history. replaceState ()
, URL-адрес может измениться, что сделает недействительным кеш параметров и их значений.
Эта версия будет обновлять свой внутренний кеш параметров каждый раз при изменении истории.
Roshambo на snipplr.com предлагает простой сценарий для достижения этой цели, описанный в Получение параметров URL с помощью jQuery | Улучшено . С его сценарием вы также легко можете выбрать только те параметры, которые вам нужны.
Вот суть:
$.urlParam = function(name, url) {
if (!url) {
url = window.location.href;
}
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
if (!results) {
return undefined;
}
return results[1] || undefined;
}
Затем просто получите свои параметры из строки запроса.
Итак, если строка URL / запроса была xyz.com/index.html?lang=de
.
Просто вызовите var langval = $ .urlParam ('lang');
, и все готово.
У UZBEKJON есть отличная запись в блоге по этому поводу, Получение параметров и значений URL с помощью jQuery .
Некоторые из размещенных здесь решений неэффективны. Повторять поиск по регулярному выражению каждый раз, когда скрипту нужно получить доступ к параметру, совершенно излишне, достаточно одной функции для разделения параметров на объекты в стиле ассоциативного массива. Если вы не работаете с HTML 5 History API, это необходимо только один раз при загрузке страницы. Другие предложения здесь также не могут правильно декодировать URL.
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
Пример строки запроса:
?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty
Результат:
urlParams = {
enc: " Hello ",
i: "main",
mode: "front",
sid: "de8d49b78a85a322c4155015fdce22c4",
empty: ""
}
alert(urlParams["mode"]);
// -> "front"
alert("empty" in urlParams);
// -> true
Это можно легко улучшить для обработки строк запросов в стиле массива. Примером может служить здесь, но поскольку параметры в стиле массива не определены в RFC 3986, я не буду засорять этот ответ исходным кодом. Для тех, кто заинтересован в "загрязненной" версии, посмотрите ответ campbeln ниже.
Также, как указано в комментариях, ;
является законным разделителем для пар ключ=значение
. Для обработки ;
или &
потребуется более сложный regex, который, на мой взгляд, не нужен, поскольку ;
используется редко, и я бы сказал, что еще более маловероятно, чтобы использовались оба варианта. Если вам нужно поддерживать ;
вместо &
, просто поменяйте их местами в regex.
<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>
Намного проще!
function GET() {
var data = [];
for(x = 0; x < arguments.length; ++x)
data.push(location.href.match(new RegExp("/\?".concat(arguments[x],"=","([^\n&]*)")))[1])
return data;
}
example:
data = GET("id","name","foo");
query string : ?id=3&name=jet&foo=b
returns:
data[0] // 3
data[1] // jet
data[2] // b
or
alert(GET("id")[0]) // return 3